这里的问题是,默认情况下,不能在 Haskell 中打印值。 print 函数和 GHCi REPL 等使用的默认打印方式是 show 函数,由类型类 Show 定义。
然后,您得到的错误是通知您已评估了一个类型的表达式,该类型没有定义 Show 的实例。模数一些废话,这就是错误消息的全部内容:
No instance for (Show ((t -> t1) -> t -> t1))
((t -> t1) -> t -> t1) 类型是为您评估的表达式推断的。这是 Church 数字 1 的有效类型,但 Church 数字的“正确”类型实际上应该是 (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))
这只是建议您可以通过定义它所期望的实例来修复错误。
现在,您可能想实际打印您的 Church 数字,而不仅仅是知道为什么不能。不幸的是,这并不像添加它要求的实例那么简单:如果您为(a -> a) -> a -> a 编写一个实例,Haskell 会将其解释为任何特定a 的实例,而正确的解释Church 数字的 of 是一个多态函数,适用于任意 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"
等等