在搜索有关 Raymond Smullyan 的To Mock a Mockingbird的信息时,我偶然发现了Stephen Tetley 的基本组合器的 Haskell 代码。我认为这是一个有趣的想法,并决定使用这些组合器来实现To Mock a Mockingbird第 24 章中的“可以做算术的鸟”。我已经定义了真、假、继任者、前任和零校验组合器,以及将组合布尔值更改为 Haskell 布尔值的函数,反之亦然。但是当我尝试创建一个接受组合数字并返回整数的函数时,我一直遇到问题。我想知道如何使这个功能工作。这是我到目前为止所得到的:
-- | The first 7 combinators below are from Stephen Tetley's Data.Aviary.Birds
-- | (http://hackage.haskell.org/package/data-aviary-0.2.3/docs/Data-Aviary-Birds.html),
-- | with minor modifications.
-- | S combinator - starling.
-- Haskell: Applicative\'s @(\<*\>)@ on functions.
-- Not interdefined.
st :: (a -> b -> c) -> (a -> b) -> a -> c
st f g x = f x (g x)
-- | K combinator - kestrel - Haskell 'const'.
-- Corresponds to the encoding of @true@ in the lambda calculus.
-- Not interdefined.
ke :: a -> b -> a
ke a _b = a
-- | I combinator - identity bird / idiot bird - Haskell 'id'.
id' :: a -> a
id' = st ke ke
-- | B combinator - bluebird - Haskell ('.').
bl :: (b -> c) -> (a -> b) -> a -> c
bl = st (ke st) ke
-- | C combinator - cardinal - Haskell 'flip'.
ca :: (a -> b -> c) -> b -> a -> c
ca = st(st(ke st)(st(ke ke)st))(ke ke)
-- | T combinator - thrush.
-- Haskell @(\#)@ in Peter Thiemann\'s Wash, reverse application.
th :: a -> (a -> b) -> b
th = ca id'
-- | V combinator - vireo.
vr :: a -> b -> (a -> b -> d) -> d
vr = bl ca th
-- | The code I added begins here.
-- | Truth combinator. Functionally superfluous since it can
-- | be replaced with the kestrel. Added for legibility only.
tr :: a -> b -> a
tr = ke
-- | Falsity combinator.
fs :: a -> b -> b
fs = ke id'
-- | Successor combinator.
sc :: a -> ((b -> c -> c) -> a -> d) -> d
sc = vr fs
-- | Predecessor combinator.
pd :: ((((a -> a) -> b) -> b) -> c) -> c
pd = th (th id')
-- | Zerocheck combinator.
zc :: ((a -> b -> a) -> c) -> c
zc = th ke
-- | Below are 2 functions for changing combinatory booleans
-- | to Haskell booleans and vice versa. They work fine as
-- | far as I can tell, but I'm not very confident about
-- | their type declarations. I just took the types
-- | automatically inferred by Haskell.
-- | Combinatory boolean to Haskell boolean.
cbhb :: (Bool -> Bool -> Bool) -> Bool
cbhb cb = cb True False
-- | Haskell boolean to combinatory boolean.
hbcb :: Bool -> a -> a -> a
hbcb hb | hb = tr
| not hb = fs
-- | Combinatory number to Haskell number.
-- | This is the problematic function that I'd like to implement.
-- | I think the function is logically correct, but I have no clue
-- | what its type would be. When I try to load it in Hugs it
-- | gives me a "unification would give infinite type" error.
cnhn cn | cbhb (zc cn) = 0
| otherwise = 1 + cnhn (pd cn)
这是我对代码问题的粗略猜测:“cnhn”函数将任何组合数字作为参数。但是不同的组合数有不同的类型,比如
零)id' :: a -> a
一)vr(ke id')id' :: ((a -> b -> b) -> (c -> c) -> d) -> d
二)vr(ke id')(vr(ke id')id') :: ((a -> b -> b) -> (((c -> d -> d) -> (e -> e ) -> f) -> f) -> g) -> g
等等。因此,将任何组合数作为参数的函数必须能够采用无限多种类型的参数。但是 Haskell 不允许这样的功能。
简而言之,这是我的 3 个主要问题:
1) 'cnhn' 函数有什么问题?(我上面的猜测正确吗?)
2)可以修复吗?
3)如果不是,我可以使用什么其他语言来实现 Smullyan 的算术鸟?
感谢您阅读一个很长的问题。