问题描述
我正在关注维基百科上关于如何处理教会文字的指南。根据文章,有一个 Haskell 片段:
type Church a = (a -> a) -> a -> a
church :: Integer -> Church Integer
church 0 = \f -> \x -> x
church n = \f -> \x -> f (church (n-1) f x)
unchurch :: Church Integer -> Integer
unchurch cn = cn (+ 1) 0
但是,当我尝试通过 GHCI 运行它时,出现以下错误:
main.hs:3:15: error:
* Expecting one more argument to `Church'
Expected a type,but `Church' has kind `* -> *'
* In the first argument of `Show',namely `Church'
In the instance declaration for `Show Church'
|
3 | instance Show Church where
我尝试在类型上使用 deriving show
并且还
instance Show Church Integer where
show = church
不幸的是,两者都产生了更多错误。我不确定函数声明中的 Church Integer
是什么意思,或者这是否是我无法导出 show 的原因?
如何打印这个函数?
解决方法
惯用的方式是将其定义为newtype,a
也应该通用量化
>> church 10
10
{-# Language GADTs #-}
{-# Language InstanceSigs #-}
{-# Language RankNTypes #-}
{-# Language ScopedTypeVariables #-}
{-# Language StandaloneKindSignatures #-}
{-# Language TypeApplications #-}
import Data.Kind
type Church :: Type
newtype Church where
Church :: (forall a. (a -> a) -> (a -> a)) -> Church
church :: Integer -> Church
church n = Church (ch n) where
ch :: Integer -> forall a. (a -> a) -> (a -> a)
ch 0 succ zero = zero
ch n succ zero = succ (ch (n-1) succ zero)
unchurch :: Church -> Integer
unchurch (Church church) = church @Integer (+ 1) 0
instance Show Church where
show :: Church -> String
show = show . unchurch