列表填充函数类型的问题

Trouble with list padding function types

我正在开发一个用 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]

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

谢谢

修复方法如下:

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都是相同类型的列表,即都是Int列表。或者你可以使用 (0:x).

此外,length x returns 是 Int,不是一般的 Num a,所以你不能使用 a 作为第二个参数的类型。

这里有几处错误,所以让我们分解一下:

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 必须有一个 Num 实例。这肯定不是你想要的。

相反,您想将 [0] 的列表添加到 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