我试图解决最大子序列和问题并提出了一个neato解决方案
msss :: (Ord a, Num a) => [a] -> a
msss = f 0 0
f gmax _ [] = gmax
f gmax lmax (x:xs) =
let g = max (lmax + x)
in f (g gmax) (g 0) xs
您调用包装函数msss
,然后调用f
,这反过来又实际完成了工作。解决方案很好,而且 afaik 工作正常。如果由于某种原因我必须解决生产代码中的最大子序列和问题,那我就是这样做的。
然而,这个包装函数真的让我很烦。我喜欢在 haskell 中的方式,如果你足够坚持,你可以在一行上编写你的整个程序,真正让人们明白程序几乎只是一个大表达式。所以我想我会尝试消除包装函数来应对额外的挑战。
现在我遇到了经典问题:如何进行匿名递归?当你不能给函数命名时,你如何进行递归?值得庆幸的是,计算之父很久以前就通过发现定点组合器解决了这个问题,其中最受欢迎的是Y 组合器。
我已经进行了各种尝试来设置 Y 组合器,但它们无法通过编译器。
msss' :: [Int] -> Int
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)
只是给
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.
改变从 只是f (y y f)
给f (y f)
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.
我已经尝试通过仅在外部定义组合器来采用不同的方法,但这仍然不起作用,并且并没有真正满足我在一个表达式中完成它的挑战。
y f = f (y f)
msss' :: [Int] -> Int
msss' = y (\g' gmax lmax list -> if list == []
then gmax
else g' (max gmax lmax + head list)
(max 0 lmax + head list)
tail list)
你能看出我在做什么有什么问题吗?我不知所措。对构造无限类型的抱怨真的让我很生气,因为我认为 Haskell 就是这样的事情。它有无限的数据结构,那么为什么会有无限类型的问题呢?我怀疑这与显示无类型 lambda 演算不一致的悖论有关。不过我不确定。如果有人能澄清一下就好了。
另外,我的印象是递归总是可以用折叠函数来表示。谁能告诉我如何仅使用折叠来做到这一点?尽管如此,代码是单个表达式的要求仍然存在。