在Haskell中导出Eq和Show for type别名

时间:2013-02-22 02:07:48

标签: haskell functional-programming typeclass

我有以下类型别名

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吗?

2 个答案:

答案 0 :(得分:6)

类型类实例只能为“真实”类型定义,如datanewtype声明所定义。 type声明是“假”类型 - 只是较长类型的缩写。

但在这种情况下,这只是问题#1。问题#2即使你这样做......

newtype Function = Function (Argument -> Store -> Value)

... Show可能仍然没有真正有用的Function实例。如何将函数转换为字符串?有两种策略。首先,“放弃”战略:

instance Show Function where
    show _ = "<some Function, no clue what it does>"

其次,“规范示例”策略,您将Function应用于某些规范ArgumentStore,并将其与Value结果一起显示:

instance Show Function where
    show (Function fn) = "Function: " 
                      ++ show defaultArgument 
                      ++ " -> " 
                      ++ show defaultStore
                      ++ " -> " 
                      ++ show (fn defaultArgument defaultStore)

这里的想法是将Function显示为它的一个特定参数/值映射,它可以帮助您更精确地识别它,而不仅仅是为所有这些使用相同的常量字符串。这有助于否取决于你的功能。

但现在我们遇到问题#3:这些都不遵守ShowRead类的意图/合同,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>"