Y combinator, Infinite types and Anonymous recursion in Haskell
我试图解决最大子序列和问题,并提出了一个neato解决方案
1 2 3 4 5 6 7 |
您调用包装函数
解决方案很好,afaik工作正常。如果由于某种原因我必须解决生产代码中的最大子序列和问题,那就是我会这样做的。
然而,包装函数确实让我感到困惑。我喜欢它如何在haskell中,如果你足够坚持,你可以将你的整个程序写在一条线上,真正让家庭认为程序几乎只是一个大表达。所以我想我会尝试消除额外挑战的包装函数。
现在我遇到了经典问题:如何进行匿名递归?当你不能给函数命名时,你如何做递归?值得庆幸的是,计算机的父亲们通过发现定点组合器解决了这个问题,其中最受欢迎的是Y Combinator。
我已经做了各种尝试来设置Y组合器,但它们无法通过编译器。
1 2 3 4 5 6 7 8 |
只是给
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 Prelude> :l C:\maxsubseq.hs
[1 of 1] Compiling Main ( C:\maxsubseq.hs, interpreted )
C:\maxsubseq.hs:10:29:
Occurs check: cannot construct the infinite type:
t0 = t0 -> (([Int] -> Int) -> [Int] -> Int) -> [Int] -> Int
In the first argument of `y', namely `y'
In the first argument of `f', namely `(y y f)'
In the expression: f (y y f) x
C:\maxsubseq.hs:11:29:
Occurs check: cannot construct the infinite type:
t0 = t0 -> (([Int] -> Int) -> [Int] -> Int) -> [Int] -> Int
In the first argument of `y', namely `y'
In the first argument of `f', namely `(y y f)'
In the expression: f (y y f) x
C:\maxsubseq.hs:12:14:
The lambda expression `\ g' gmax lmax list -> ...'
has four arguments,
but its type `([Int] -> Int) -> [Int] -> Int' has only two
In the second argument of `\ y f x -> f (y y f) x', namely
`(\ g' gmax lmax list
-> if list == [] then
gmax
else
g' (max gmax lmax + head list) (max 0 lmax + head list) tail list)'
In the expression:
(\ y f x -> f (y y f) x)
(\ y f x -> f (y y f) x)
(\ g' gmax lmax list
-> if list == [] then
gmax
else
g' (max gmax lmax + head list) (max 0 lmax + head list) tail list)
In an equation for `msss'':
msss'
= (\ y f x -> f (y y f) x)
(\ y f x -> f (y y f) x)
(\ g' gmax lmax list
-> if list == [] then
gmax
else
g' (max gmax lmax + head list) (max 0 lmax + head list) tail list)
Failed, modules loaded: none.
从
1
2
3
4
5
6
7
8 C:\maxsubseq.hs:11:29:
Couldn't match expected type `[Int] -> Int'
with actual type `[Int]'
Expected type: (([Int] -> Int) -> t1 -> t0) -> t2 -> t0
Actual type: ([Int] -> Int) -> t1 -> t0
In the first argument of `y', namely `f'
In the first argument of `f', namely `(y f)'
Failed, modules loaded: none.
我尝试通过外部定义组合子来采用不同的方法,但是这仍然不起作用,并没有真正满足我在一个表达式中执行它的挑战。
1 2 3 4 5 6 7 8 |
你能发现我正在做的事情有什么问题吗?我不知所措。关于构建无限类型的抱怨真的让我感到震惊,因为我虽然Haskell完全是关于那种事情。它具有无限的数据结构,那么为什么无限类型的问题呢?我怀疑它与该悖论有关,这表明无类型的lambda演算是不一致的。我不如果有人能澄清,那就好了。
此外,我的印象是递归始终可以用折叠函数表示。任何人都可以告诉我如何通过使用折叠来做到这一点?代码是单个表达式的要求仍然存在。
您无法在Haskell中定义Y组合器。正如您所注意到的那样,这会导致无限类型。幸运的是,它已在
1 | fix f = let x = f x in x |
因为Y组合器需要无限类型,所以你需要像这样的解决方法。
但我会将你的
好吧,让我们考虑一下。这个lambda表达式有什么类型?
1 | (\y f x -> f (y y f) x) |
井
1 | (y y f) :: (a -> b) |
此外,由于我们将此表达式应用于自身,因此我们知道
所以
1 | y :: f1 -> ((a -> b) -> a -> b) -> (a -> b) |
问题是......什么是
1 | f1 = f1 -> ((a -> b) -> a -> b) -> (a -> b) |
如果你想要一个独立的"单行",那么请改为使用hammar的建议:
1 2 3 4 5 |
虽然imho if