如何在Haskell中实现++?

use*_*256 3 haskell

嗨,我是Haskell编程的新手.我正在尝试自己实现运算符"++".这是我写的一个小程序,但它不起作用:

append (es:e) xs = 
    if (null es)
    then e:xs
    else append es (e:xs)
Run Code Online (Sandbox Code Playgroud)

我收到了很多关于[a],[[a]]和[[[a]]]的类型错误.关于Haskell中的列表类型仍然令人困惑.有人可以帮助我吗?谢谢.:)

Ber*_*rgi 20

append (es:e) xs =
        ^^^^
Run Code Online (Sandbox Code Playgroud)

通常情况下,你会写(e:es),可以说"在es列表之前一个e".你实际上已经在下面使用了这个含义,但已告诉编译器这es是一个元素并且e是一个列表 - 它会产生你收到的类型错误.

    if (null es)
Run Code Online (Sandbox Code Playgroud)

这不是你应该如何测试一个emtpy列表.事实上,如果你打电话给append [] …你,你会得到一个"非详尽的模式"错误,因为(e:es)它始终是至少一个元素的列表.所以尝试两种模式:

append []     xs = xs
append (e:es) xs = append es (e:xs)
Run Code Online (Sandbox Code Playgroud)

但是,这仍然无法工作 - 第一个列表实际上是通过此代码段反转的.相反,第一个元素(e)需要在列表的其余部分之前(esxs):

append (e:es) xs = e : (append es xs)
Run Code Online (Sandbox Code Playgroud)

(这确实是如何++实现的)

  • @bheklilr` augment`在融合规则"foldr/augment"forall kz xs(g :: forall b.(a-> b-> b) - > b - > b)时给出优化.foldr kz(augment g xs)= gk(foldr kz xs)`,理想地优化了大部分列表分配.`augment`与类似的`build`不同之处在于它用于将东西添加到列表中而不是构建整个列表.参见[GHC.Base](http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.7.0.1/src/GHC-Base.html#%2B%2B). (3认同)