我指的是this question
type Churchlist t u = (t->u->u)->u->u
在lambda演算中,列表编码如下:
[] := λc. λn. n
[1,2,3] := λc. λn. c 1 (c 2 (c 3 n))
mapChurch :: (t->s) -> (Churchlist t u) -> (Churchlist s u)
mapChurch f l = \c n -> l (c.f) n
我正在思考我可以在Churchlists上实现的其他列表函数,并成功编写了一个连接2个教会列表的conc2函数
conc2Church l1 l2 c n = l1 c (l2 c n)
我还尝试了一个zipWithChurch,它在普通列表中像zipWith一样运行。但我找不到解决方案。任何人都可以帮助我吗?
答案 0 :(得分:4)
您想使用真正的元组还是教堂元组?我会假设前者。
因此,从所需的类型签名开始。您希望它接收2个不同的Churchlist
并生成Churchlist
个元组。
churchZip :: Churchlist a u -> Churchlist b u -> Churchlist (a,b) u
现在你将如何实现这个?回想一下,Churchlist
由折叠它们的函数表示。因此,如果我们的结果是Churchlist (a,b) u
,我们希望它具有类型((a,b) -> u -> u) -> u -> u
的函数形式(毕竟,这相当于类型同义词Churchlist (a,b) u
)。
churchZip l1 l2 c n = ???
下一步是什么?嗯,这取决于。 l1
是空的吗?那么l2
呢?如果其中任何一个是,那么您希望结果为空列表。否则,你想要对每个列表中的第一个元素进行配对,然后教会使用其他元素。
churchZip l1 l2 c n
| isEmpty l1 || isEmpty l2 = n
| otherwise = c (churchHead l1, churchHead l2)
(churchZip (churchTail l1) (churchTail l2) c n
这提出了一些问题。
churchHead
,churchTail
和isEmpty
吗?你愿意写吗?你能写出来吗?l1
和l2
实际上 折叠函数本身就是,但这是一个干净的解决方案吗?如果对教会的名单编码有充分的了解,那么完全达到这一点是纯粹机械的。我会把深思熟虑留给你,因为这个是作业。