列表填充功能类型有问题

时间:2015-01-28 20:21:19

标签: haskell functional-programming

我正在处理一个函数,该函数用0填充Num列表,直到它至少与请求的长度一样长。

main = do
       putStrLn $ show ( padList [1,2,3] 5)

padList :: (Num a) => [a] -> a -> [a]                  
padList x len = if length(x) >= len then x else padList ((x ++ 0) len)

但我一直在接受:

prog.hs:9:49:
    Couldn't match expected type `[a]'
                with actual type `Integer -> [Integer]'
    In the return type of a call of `padList'
    Probable cause: `padList' is applied to too few arguments
    In the expression: padList (([0] : x) len)
    In the expression:
      if length (x) >= len then x else padList ((x ++ 0) len)

有人能指出我正确的方向吗?

我试图将x附加到列表[0],直到我得到:

[1,2,3,0,0]

但是,我的列表可能是浮动的,所以: [1.0,2.0,3.0]可能会变成=> [1.0,2.0,3.0,0.0,0.0]

我不太关心性能,我只是想学习函数式编程。

由于

2 个答案:

答案 0 :(得分:3)

以下是如何修复它:

padList :: (Num a) => [a] -> Int -> [a]
                             ^^^
padList x len = if length(x) >= len then x else padList ([0] ++ x) len
                                                        ^^^^^^^^^^

表达式([0]:x)表示x是列表,[0]表示x的元素。也就是说,x是Ints列表的列表。

表达式[0] ++ x表示[0]x都是相同类型的列表,即两者都是Ints列表。或者,您可以使用(0:x)

此外,length x会返回一个Int,而非一般Num a,因此您无法使用a作为第二个参数的类型。

答案 1 :(得分:1)

这里有一些问题,所以让我们分解一下:

padList :: (Num a) => [a] -> a -> [a]                  
padList x len = if length(x) >= len then x else padList ((x ++ 0) len)

长度类型为length :: [a] -> Int,因此在比较length x >= len时强制lenInt类型。由于需要更具体的类型,因此您声明的内容将引发错误。这可以通过更改类型签名来修复。

padList :: (Num a) => [a] -> Int -> [a] 

现在类型正确,但功能仍然不正确。 (++)的类型是(++) :: [a] -> [a] -> [a],这意味着它期望所有元素都是相同的类型。

如果您要定义功能

padList x len = if length(x) >= len then x else padList (x ++ 0) len

没有类型签名,由于Num类型类,编译器实际上除了它之外。但推断类型为Num [a] => [a] -> Int -> [a]

这是因为您在执行(x++0)时实际执行的操作我的x类型为[a]0类型为Num a => a (++)所以,如果我能够对这两个项目使用Num [a] => a,那么[0]必须有一个Num实例。这肯定不是你想要的。

相反,您想要将x的列表添加到padList x len = if length(x) >= len then x else padList ((x ++ [0]) len)

`padList' is applied to too few arguments

现在回答你的原始问题,你得到的错误

((x ++ [0]) len)

是因为您的额外括号使编译器认为(x ++ [0])是一个参数,它认为您将len应用于padList x len = if length(x) >= len then x else padList (x ++ [0]) len 。你不想要括号

length(x)

也需要length x周围的那个,你可以做{{1}}