所以我正在编写一个程序,它返回一个给定算术问题的过程,所以我想实现一些Show的函数,以便我可以打印我测试时评估的相同表达式.问题是给定的代码匹配( - )到第一行时应该落到第二行.
{-# OPTIONS_GHC -XFlexibleInstances #-}
instance Show (t -> t-> t) where  
 show (+) = "plus"
 show (-) = "minus"  
main = print [(+),(-)]
回报
[plus,plus]
我只是首先承诺一个致命的印刷功能,还是有一些方法可以让它正确匹配?
编辑:我意识到我收到以下警告:
Warning: Pattern match(es) are overlapped
         In the definition of `show': show - = ...
我仍然不知道为什么它会重叠,或者如何阻止它.
这是一种思考这个问题的方法.考虑:
answer = 42
magic = 3
specialName :: Int -> String
specialName answer = "the answer to the ultimate question"
specialName magic = "the magic number"
specialName x = "just plain ol' " ++ show x
你能明白为什么这不起作用吗?answer模式匹配中的变量是一个变量,answer与外部范围不同.所以相反,你必须这样写:
answer = 42
magic = 3
specialName :: Int -> String
specialName x | x == answer = "the answer to the ultimate question"
specialName x | x == magic = "the magic number"
specialName x = "just plain ol' " ++ show x
实际上,这就是在模式中编写常量时正在发生的事情.那是:
digitName :: Bool -> String
digitName 0 = "zero"
digitName 1 = "one"
digitName _ = "math is hard"
由编译器转换为等效于:
digitName :: Bool -> String
digitName x | x == 0 = "zero"
digitName x | x == 1 = "one"
digitName _ = "math is hard"
由于您希望匹配绑定的函数(+)而不是仅将任何内容绑定到符号(+),因此您需要将代码编写为:
instance Show (t -> t-> t) where  
 show f | f == (+) = "plus"
 show f | f == (-) = "minus"
但是,这将要求功能在平等性方面具有可比性. 这一般是一个不可判定的问题.
您可能会反驳说您只是要求运行时系统比较函数指针,但在语言级别,Haskell程序员无法访问指针.换句话说,您不能在Haskell(*)中操作对值的引用,只能自己赋值.这是Haskell的纯度,并获得参考透明度.
(*)MVars和IOmonad中的其他此类对象是另一回事,但它们的存在并不会使这一点无效.
正如sepp2k和MtnViewMark所说,你不能在标识符的值上进行模式匹配,只能在构造函数上进行模式匹配,在某些情况下,也不能进行隐式相等性检查.因此,您的实例将任何参数绑定到标识符,在此过程中影响外部定义(+).不幸的是,这意味着你要做的事情不会也不会有效.
要实现的目标的典型解决方案是使用适当的show实例定义"算术表达式"代数数据类型.请注意,您可以使表达式类型本身成为一个实例Num,其中包含在"Literal"构造函数中的数字文字,以及(+)返回其参数与操作的构造函数相结合的操作.这是一个快速,不完整的例子:
data Expression a = Literal a
                  | Sum (Expression a) (Expression a)
                  | Product (Expression a) (Expression a)
                  deriving (Eq, Ord, Show)
instance (Num a) => Num (Expression a) where
    x + y = Sum x y
    x * y = Product x y
    fromInteger x = Literal (fromInteger x)
evaluate (Literal x) = x
evaluate (Sum x y) = evaluate x + evaluate y
evaluate (Product x y) = evaluate x * evaluate y
integer :: Integer
integer = (1 + 2) * 3 + 4
expr :: Expression Integer
expr = (1 + 2) * 3 + 4
在GHCi中尝试:
> integer
13
> evaluate expr
13
> expr
Sum (Product (Sum (Literal 1) (Literal 2)) (Literal 3)) (Literal 4)