繁体   English   中英

使用文件夹的Haskell错误

[英]Haskell error using foldr

我是Haskell的新手,并尝试了一些练习

我不明白错误产生的原因以及产生原因

split = foldr 
        (\x y -> y:x)
        [[]]

解释器上的错误如下

    Occurs check: cannot construct the infinite type: a0 = [a0]
    In the first argument of `(:)', namely `y'
    In the expression: y : x
    In the first argument of `foldr', namely `(\ x y -> y : x)'
Failed, modules loaded: none.

有人可以帮忙吗? 提前致谢

文件夹类型为

foldr :: (a -> b -> b) -> b -> [a] -> b

所以在分裂

split = foldr (\x y -> y:x) [[]]

yy:x必须具有相同的类型,这对于任何xy都是不可能的,因为y:x在列表中始终比y更深一步。

我想你想做x:y吗?

回忆文件foldr的类型: (a -> b -> b) -> b -> [a] -> b foldr (a -> b -> b) -> b -> [a] -> b 这表示foldr需要一个函数,该函数将列表的元素与最终结果类型的值组合在一起,从而产生结果类型的新值。

对于第一个参数,您给了foldr函数\\xy -> y:x ,其中x是列表元素, y是下一步的结果; 并且应用此lambda的结果应与y具有相同的类型。

但是(:)的类型是a -> [a] -> [a] -也就是说,它将单个元素附加到列表的开头。 在表达式y:x ,您将采用某种“结果”类型,并将其用作用作结果的列表的元素。

因此,GHC尝试推断结果类型b与类型[b]相同,然后当然与类型[[b]][[[b]]] ...等等。 因此,它抱怨“无限类型”。

在我之前的帖子回答了您的问题,但是在您发表评论之后,我可以看到您想要一个按谓词将列表分开的函数。

您可以使用模块GHC.Exts中的groupWith :: Ord b =>(a-> b)-> [a]-> [[a]],并在您的模块中为其提供类型为(a-> Bool)的函数例:

groupWith even [1,2,3,4,5,6] yields [[1,3,5],[2,4,6]]

另外,有些丑陋但可以实现所需的“外出”类型的东西是:

split::Eq a => (a -> Bool) -> [a] -> [[a]]
split f ls = (ls \\ rl):rl:[]
    where rl = filter f ls

但是,由于您提供的二进制函数,总是会将提供的列表分成两个列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM