Haskell 教堂数字无法打印 |需要一个类型,但 T 有类型 `f`

问题描述

我正在关注维基百科上关于如何处理教会文字的指南。根据文章,有一个 Haskell 片段:

维基链接Here

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