关于Haskell中的scanl1

时间:2011-01-19 17:34:34

标签: haskell

函数应返回列表的运行总和。比如使用[1,2,3,5]调用它会返回[1,3,6,11]

我写了这个函数如下:

sumlist' :: [xx]=[xx]
sumlist' []=[]
sumlist' [x]=x
sumlist' xx=scanl1 (+) [xx]

当我在GHcI中运行它时,它向我显示我做了多个声明。那么这个功能有什么问题呢?

3 个答案:

答案 0 :(得分:4)

首先,您要将声明更改为

sumlist' :: [xx]->[xx]

因为sumlist'采用xx类型的List并返回xx类型的List。

由于我们在调用scanl1时使用(+),而(+)需要类型Num,我们需要回到sumlist的定义并告诉它我们特别列出Nums。

sumlist' :: Num xx=>[xx]->[xx]

scanl1可以处理空列表,所以你需要的只是

sumlist' :: Num xx=>[xx]->[xx]
sumlist' xx = scanl1 (+) xx


但是,如果你仍然只是为了踢,想要尝试你的代码,你需要修复最后两行:

对于x包含 1 元素的情况,您有:

sumlist' [x] = x

请记住,sumlist'需要一个列表而返回一个列表,所以只需返回列表!

sumlist' [x] = [x]

对于最后一种情况,你拿一个名为xx的列表,你有

sumlist' xx=scanl1 (+) [xx]

xx已经是一个列表,因此GHC会认为[xx]列表,所以只需删除括号

sumlist' xx=scanl1 (+) xx

因此我们修改后的代码类似于:

sumlist' :: Num xx=>[xx]->[xx]
sumlist' []=[]
sumlist' [x]=[x]
sumlist' xx=scanl1 (+) xx

ephemient所述,如果需要向GHCi输入多行,请使用:load命令。

希望这有帮助,并且快乐的黑客行为: - )

答案 1 :(得分:0)

sumlist' :: [xx]=[xx]

那条线是错的。 ::之后的部分应该是类型声明,看起来像[a] -> [a]。 (是的,它看起来像模式/值[xx],但不是。)

不要尝试在GHCi中输入多行声明,它会分别处理每个输入行。只需将其保存在文件中,并将:load文件保存在GHCi中。

答案 2 :(得分:0)

这不是您问题的直接答案,但使用高阶函数定义sumList的更好方法是:

sumList :: (Num a) => [a] -> [a]
sumList = tail . scanl (+) 0

另请注意,尽管=明显错误->,但您的类型签名“过于多态”,因为您的函数仅适用于{{1中的某些类型的列表}“class”,而不是“任何类型的列表”。