我有以下类型别名
data Bindable = Const Value
| Variable Location
| Func Function
| Proc
deriving (Eq, Show)
type Function = Argument -> Store -> Value
但是编译器给了我一个错误
No instance for (Show Function)
arising from the 'deriving' clause of a data type declaration
Possible fix:
add an instance declaration for (Show Function)
or use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Show Bindable)
我可以定义Show& Eq功能?如果没有那么解决方案是什么?我应该定义Eq和Show to Argument,Store和Value吗?
答案 0 :(得分:6)
类型类实例只能为“真实”类型定义,如data
或newtype
声明所定义。 type
声明是“假”类型 - 只是较长类型的缩写。
但在这种情况下,这只是问题#1。问题#2即使你这样做......
newtype Function = Function (Argument -> Store -> Value)
... Show
可能仍然没有真正有用的Function
实例。如何将函数转换为字符串?有两种策略。首先,“放弃”战略:
instance Show Function where
show _ = "<some Function, no clue what it does>"
其次,“规范示例”策略,您将Function
应用于某些规范Argument
和Store
,并将其与Value
结果一起显示:
instance Show Function where
show (Function fn) = "Function: "
++ show defaultArgument
++ " -> "
++ show defaultStore
++ " -> "
++ show (fn defaultArgument defaultStore)
这里的想法是将Function
显示为它的一个特定参数/值映射,它可以帮助您更精确地识别它,而不仅仅是为所有这些使用相同的常量字符串。这有助于否取决于你的功能。
但现在我们遇到问题#3:这些都不遵守Show
和Read
类的意图/合同,read (show x)
等同于x
。 (人们经常会忽略这个意图,只是因为他们想要打印某些东西并且Show
是最快的票。正如Thomas DuBuisson指出的那样,有一个标准模块{ {1}}实现“放弃”策略。)
至于Text.Show.Functions
类,答案是一般来说,比较两个函数是否相等是不可能的。 (如果我没记错的话,它等同于解决停机问题,但不要引用我。)如果你的解决方案要求你比较功能是否相等,你需要一个新的解决方案......
答案 1 :(得分:5)
只需导入Text.Show.Functions
即可。您的type
只是一个别名,错误消息是它找不到Show (->)
的实例,但该模块中有一个实例。
Prelude> import Text.Show.Functions
Prelude Text.Show.Functions> show (+1)
"<function>"