我阅读了有关如何创建自定义Prelude库的this博文。可以找到该库here。它所做的一件事是禁止String
。它还定义了自动字符串转换的函数(here)。我在cabal文件中启用了OverloadedStrings
。
在使用这个库之前,我有:
data Point = Point Int Int
instance Show Point where
show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")"
使用图书馆后,它说:" show' is not a (visible) method of class
显示'"
所以我使用创建自定义函数来显示数据类型:
showPoint :: Point -> LText
showPoint (Point x y) = toS ("(" ++ show x ++ ", " ++ show y ++ ")")
编译器说toS, "(", show
的使用含糊不清,但我不明白为什么。我是否必须做一些像here提议的内容?
修改
必须禁用OverloadedStrings并将代码更改为以下内容:
showPoint :: Point -> LText
showPoint (Point x y) = toS "(" <> show x <> toS ", " <> show y <> toS ")"
想知道是否可以在不禁用OverloadedStrings的情况下执行相同操作,因此我不必为toS
String
使用data
。
答案 0 :(得分:2)
这对我有用:
{-# LANGUAGE OverloadedStrings #-}
module Test where
import Protolude
import qualified Base as PBase
data P = P Int
instance PBase.Show P where
show (P x) = "a P " ++ show x
<强>更新强>
show
的protolude实现是一个正常的函数(参见Protolude.hs的结尾):
show :: (Show a, StringConv String b) => a -> b
show x = toS (PBase.show x)
因此,您需要一个PBase.Show
实例才能使用protolude的show函数。
protolude的show
也可以返回任何字符串类型,因此您不会通过定义PBase.show实例来强制其他人使用String。
更新#2
您可以从show
导入类型GHC.Show
函数:
{-# LANGUAGE NoImplicitPrelude #-}
import Protolude
import GHC.Show
data P = P Int
instance Show P where
show (P x) = "<-- P " ++ GHC.Show.show x ++ " -->"
main = print (P 123)
答案 1 :(得分:1)
可能由以下原因引起:
show
可以生成任何类似字符串的类型toS
可以接受多种不同类型如果是这样,编译器不知道要选择哪个类似中间字符串的类型,并且抛出了歧义错误。