Haskell 实施Smullyan';哈斯克尔的算术鸟

Haskell 实施Smullyan';哈斯克尔的算术鸟,haskell,combinators,combinatory-logic,Haskell,Combinators,Combinatory Logic,在寻找雷蒙德·斯穆利安的《模仿一只知更鸟》的资料时,我偶然发现。我认为这是一个有趣的想法,并决定实现第24章中的“会做算术的鸟”,用这些组合器模拟一只知更鸟。我已经定义了真值、假值、后继值、前置值和零检查组合符,以及将组合布尔值转换为Haskell布尔值和将组合布尔值转换为Haskell布尔值的函数。但是,当我尝试创建一个接受组合数并返回整数的函数时,我总是遇到问题。我想知道如何使这个函数工作。以下是到目前为止我得到的信息: -- | The first 7 combinators below

在寻找雷蒙德·斯穆利安的《模仿一只知更鸟》的资料时,我偶然发现。我认为这是一个有趣的想法,并决定实现第24章中的“会做算术的鸟”,用这些组合器模拟一只知更鸟。我已经定义了真值、假值、后继值、前置值和零检查组合符,以及将组合布尔值转换为Haskell布尔值和将组合布尔值转换为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)
——|下面的前7个组合词来自Stephen Tetley的Data.Aviary.Birds
-- | (http://hackage.haskell.org/package/data-aviary-0.2.3/docs/Data-Aviary-Birds.html),
--|稍作修改。
--| S combinator-椋鸟。
--Haskell:Applicative的@(\)@函数。
--没有定义。
圣::(a->b->c)->(a->b)->a->c
st f g x=f x(g x)
--| K combinator-kestrel-Haskell“const”。
--对应于lambda演算中@true@的编码。
--没有定义。
ke::a->b->a
ke a_b=a
--| I组合器-身份鸟/白痴鸟-Haskell'id'。
id'::a->a
id'=圣科克
--| B combinator-蓝鸟-哈斯克尔('.')。
bl::(b->c)->(a->b)->a->c
bl=st(ke st)ke
--| C组合符-基数-哈斯克尔“翻转”。
ca:(a->b->c)->b->a->c
ca=st(st(ke st)(st(ke)st))(ke)
--| T组合鹅口疮。
--Haskell@(\\#)在Peter Thiemann的清洗液中,反向应用。
th::a->(a->b)->b
th=ca id'
--| V combinator-vireo。
vr::a->b->(a->b->d)->d
vr=bl-ca-th
--|我添加的代码从这里开始。
--|真理组合器。功能上多余的,因为它可以
--|被红隼取代。仅为便于阅读而添加。
tr::a->b->a
tr=ke
--|虚假组合词。
fs::a->b->b
fs=ke id'
--|后继组合器。
sc::a->((b->c->c)->a->d)->d
sc=vr-fs
--|前置组合器。
pd::(((a->a)->b)->b)->c)->c
pd=th(th id')
--|零检查组合器。
zc::((a->b->a)->c)->c
zc=th-ke
--|下面是两个用于更改组合布尔值的函数
--|哈斯克尔布尔人,反之亦然。他们工作得很好
--|据我所知,但我对
--|它们的类型声明。我只是选了类型
--|由Haskell自动推断。
--|组合布尔到Haskell布尔。
cbhb::(Bool->Bool->Bool)->Bool
cbhb cb=cb真假
--| Haskell布尔到组合布尔。
hbcb::Bool->a->a->a
hbcb hb | hb=tr
|非hb=fs
--|组合数到Haskell数。
--|这是我想要实现的有问题的函数。
--|我认为函数在逻辑上是正确的,但我没有任何线索
--|它的类型是什么。当我试着把它装进去时,拥抱它
--|给了我一个“统一会给无限类型”的错误。
cnhn cn | cbhb(zc cn)=0
|否则=1+cnhn(pd-cn)
下面是我对代码错误的粗略猜测:“cnhn”函数将任何组合数作为参数。但是不同的组合数有不同的类型,例如

零)id':a->a

一)虚拟现实(ke id’’id’:((a->b->b)->(c->c)->d)->d

二)虚拟现实(ke-id')(虚拟现实(ke-id')id')::((a->b->b)->((c->d->d)->(e->e)->f)->f)->g)->g

等等。因此,一个以任意组合数为参数的函数必须能够接受无限多种类型的参数。但是Haskell不允许这样的功能

简而言之,以下是我的三个主要问题:

1) “cnhn”功能有什么问题?(我上面的猜测正确吗?)

2) 能修好吗

3) 如果没有,我可以使用什么其他语言来实现Smullyan的算术鸟


谢谢你读了一个很长的问题

似乎后继组合器不太正确。这是Haskell中Church算法的编码,
unchurch
函数是
cnhn
(我想是Church编号到Haskell编号?)试图实现的

tr :: a -> b -> a
tr x y = x

fl :: a -> b -> b
fl x y = y

succ :: ((a -> b) -> c -> a) -> (a -> b) -> c -> b
succ n f x = f (n f x)

unbool :: (Bool -> Bool -> t) -> t
unbool n = n True False

unchurch :: ((Int -> Int) -> Int -> a) -> a
unchurch n = n (\i -> i + 1) 0

church :: Int -> (a -> a) -> a ->a
church n =
  if n == 0
  then zero
  else \f x -> f (church (n-1) f x)

zero :: a -> b -> b
zero = fl

one :: (a -> a) -> a -> a
one = succ zero

two :: (a -> a) -> a -> a
two = succ one

ten :: (a -> a) -> a -> a
ten = succ (succ (succ (succ (succ (succ (succ (succ (succ (succ zero)))))))))

main = do
  print (unchurch ten)
  print (unchurch (church 42))
所以一个以任意组合数为参数的函数必须是 能够接受无限多种类型的参数。但哈斯克尔没有 允许这样的功能

啊,但确实如此,因为Haskell允许参数多态性。如果您查看数字的编码,它们都有签名(
(a->a)->a->a
),因此采用教堂编号的函数的参数只需要有它的第一个参数,就可以将它的第一个参数的类型变量与编码教堂编号的函数统一起来

例如,我们还可以定义一个乘法运算,它实际上只是一个高阶函数,它取两个church数并将它们相乘。这适用于任何两个教堂号码

mult :: (a -> b) -> (c -> a) -> c -> b
mult m n f = m (n f)

test :: (a -> a) -> a -> a
test = mult ten ten

main = print (unchurch test) -- 100

您需要更高级别的类型来为Haskell中Church编码的自然对象提供合理的类型。或者,
Church n=foldr(.)id。复制n
我只是再次查阅了这本书,发现这本书中使用的数值格式是由Henk Barendregt发明的,与Church的类似但不同。在这个方案中,后继组合子被定义为V(KI),其中Vxyz=zxy,Kxy=x,Ix=x。因此,尽管
unchurch
为Church算术做了我试图用
cnhn
做的事情,我想知道是否有一个函数可以为Barendregt算术做这件事。不过,我知道你对参数多态性的看法是正确的。显然,Haskell允许这样做,因为有许多函数接受多种类型的参数,例如,
id
。因此,
cnhn
的问题肯定是别的。在巴伦德雷格算法中没有这样的东西。您所描述的方案正是church算法,只是其中的参数