派生Eq和显示Haskell中的类型别名 [英] Derive Eq and Show for type alias in Haskell

查看:152
本文介绍了派生Eq和显示Haskell中的类型别名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类型的别名:

  data Bindable = Const Value 
|变量位置
| Func函数
| Proc
派生(Eq,Show)

类型Function =参数 - >商店 - >价值

但编译器给我一个错误

 没有从数据类型声明的'deriving'子句产生的(显示函数)
的实例
可能的修正:
添加实例声明(显示函数)
或使用独立的派生实例声明,
,因此您可以自己指定实例上下文
当为(Show Bindable)派生实例时

我可以定义Show& Eq功能?如果不是,那么解决方案是什么?我应该定义Eq和Show来参数,存储和值吗?

解决方案

类型类实例只能针对真实类型,由 data newtype 声明定义。一个类型声明是一个假类型 - 只是一个较长类型的缩写。



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

  newtype Function = Function(Argument  - > Store  - >价值)

...可能还没有真正有用的显示 code>实例用于函数。如何将函数转换为字符串?有两种策略。首先,放弃策略:

  instance Show Function where 
show _ =< some Function ,不知道它做什么>

其次,规范示例策略应用函数到一些规范的参数 Store ,并与结果:

 实例Show Function其中
show(Function fn)=Function :
++ show defaultArgument
++ - >
++ show defaultStore
++ - >
++ show(fn defaultArgument defaultStore)

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



但是现在我们遇到了问题3:它们都不符合显示读取类,即 read(show x)等价于 X 。 (然而,人们经常忽略这个意图,仅仅是因为他们想要打印 Show 是最快的票据。 DuBuisson指出,有一个实现了放弃策略的标准模块 Text.Show.Functions 。)



<对于 Eq 类来说,答案是一般情况下比较两个函数的相等性是不可能的。 (如果我没有记错,这相当于解决停机问题,但不要引用我的话)。如果您的解决方案要求您比较功能是否相等,则需要一个新的解决方案...


I've the following type alias

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

type Function = Argument -> Store -> Value

but the compiler gives me an error

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)

Can I define Show & Eq for Function? If not then what would be the solution? Should I define Eq and Show to Argument, Store and Value?

解决方案

Type class instances may only be defined for "real" types, as defined by a data or newtype declaration. A type declaration is a "fake" type—just an abbreviation for a longer type.

But that's just problem #1 in this case. Problem #2 is that even if you do this...

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

...there might still be no truly useful Show instance for Function. How do turn a function into a string? There are two strategies. First, the "just give up" strategy:

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

Second, the "canonical example" strategy, where you apply the Function to some canonical Argument and Store and show these together with the Value result:

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

The idea here is to display the Function as one particular argument/value mapping of it that might help you identify it more precisely than just using the same constant string for all of them. Whether this helps or not depends on what your functions do.

But now we have problem #3: neither of these obeys the intent/contract of the Show and Read classes, which is that read (show x) is equivalent to x. (People do often ignore this intent, however, just because they want to print something and Show is the quickest ticket. So much that, as Thomas DuBuisson points out, there's a standard module Text.Show.Functions that implements the "just give up" strategy.)

As for the Eq class, the answer is that it's just impossible in general to compare two functions for equality. (If I recall correctly, it's equivalent to solving the Halting Problem, but don't quote me on that.) If your solution requires you to compare functions for equality, you need a new solution...

这篇关于派生Eq和显示Haskell中的类型别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆