我正在尝试使用以下定义在haskell中打印教堂数字:

0 := λfx.x
1 := λfx.f x

Haskell代码:
c0 = \f x -> x
c1 = \f x -> f x

当我在haskell控制台中输入它时,出现错误提示
    test> c1

    <interactive>:1:0:
    No instance for (Show ((t -> t1) -> t -> t1))
      arising from a use of `print' at <interactive>:1:0-1
    Possible fix:
      add an instance declaration for (Show ((t -> t1) -> t -> t1))
    In a stmt of an interactive GHCi command: print it

我无法准确找出错误内容。

谢谢!

最佳答案

这里的问题是,默认情况下,无法在Haskell中打印值。 print函数和GHCi REPL等使用的默认打印方式是show函数,由类型类Show定义。

然后,您得到的错误通知您,您评估的表达式类型未定义Show实例。模数有些乱语,这就是所有错误消息在说:

No instance for (Show ((t -> t1) -> t -> t1))
((t -> t1) -> t -> t1)类型是为您评估的表达式所推断的类型。这是教堂数字1的有效类型,尽管教堂数字的“正确”类型实际上应该是(a -> a) -> a -> a
  arising from a use of `print' at <interactive>:1:0-1

它隐式使用print函数显示值。通常,这会告诉您在程序中的哪个位置发现了错误,但是在这种情况下,它显示为<interactive>:1:0-1,因为该错误是由REPL中的表达式引起的。
Possible fix:
  add an instance declaration for (Show ((t -> t1) -> t -> t1))

这仅表明您可以通过定义期望的实例来修复错误。

现在,您可能想要实际打印教堂的数字,而不只是知道为什么不能。不幸的是,这并不像添加它所要求的实例那么简单:如果为(a -> a) -> a -> a编写实例,Haskell会将其解释为任何特定a的实例,而正确的教堂数字解释是可以使用的多态函数。任何任意的a

换句话说,您希望自己的show函数像这样:
showChurch n = show $ n (+1) 0

如果确实需要,可以实现Show实例,如下所示:
instance (Show a, Num a) => Show ((a -> a) -> a -> a) where
    show n = show $ n (+1) 0

并将{-#LANGUAGE FlexibleInstances#-}添加到文件的第一行。或者,您可以实现类似的方法将其转换为常规数字
> churchToInt c1
1
> showChurch c1
"1"

等等。

10-08 08:50
查看更多