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

K''*_*K'' 2 haskell functional-programming typeclass

我有以下类型的别名

data    Bindable  = Const Value 
                      | Variable Location
                    | Func Function
                    | Proc
              deriving (Eq, Show)                                   

type Function = Argument -> Store -> Value
Run Code Online (Sandbox Code Playgroud)

但是编译器给了我一个错误

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)
Run Code Online (Sandbox Code Playgroud)

我可以定义Show&Eq for Function吗?如果没有那么解决方案是什么?我应该定义Eq和Show to Argument,Store和Value吗?

Lui*_*las 6

类型类实例只能为"真实"类型定义,如由datanewtype声明定义.一个type声明是"假"的类型只是一个较长的类型缩写.

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

newtype Function = Function (Argument -> Store -> Value)
Run Code Online (Sandbox Code Playgroud)

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

instance Show Function where
    show _ = "<some Function, no clue what it does>"
Run Code Online (Sandbox Code Playgroud)

第二,"规范示例"策略,您将其Function应用于某些规范Argument,Store并将其与Value结果一起显示:

instance Show Function where
    show (Function fn) = "Function: " 
                      ++ show defaultArgument 
                      ++ " -> " 
                      ++ show defaultStore
                      ++ " -> " 
                      ++ show (fn defaultArgument defaultStore)
Run Code Online (Sandbox Code Playgroud)

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

但是现在我们遇到了问题#3:这些都没有服从ShowRead类的意图/合同,这read (show x)相当于x.(人们经常忽略这个意图,只是因为他们想要打印一些东西并且Show是最快的票.就像Thomas DuBuisson指出的那样,有一个标准模块Text.Show.Functions实现了"放弃"策略.)

至于Eq班级,答案是一般来说,比较两个函数是否相等是不可能的.(如果我没记错的话,它等同于解决停机问题,但不要引用我.)如果你的解决方案要求你比较功能是否相等,你需要一个新的解决方案......


Tho*_*son 5

只需导入Text.Show.Functions.您type只是一个别名,错误消息是它找不到Show for (->)的实例,但该模块中有一个实例可用.

Prelude> import Text.Show.Functions
Prelude Text.Show.Functions> show (+1)
"<function>"
Run Code Online (Sandbox Code Playgroud)