列表填充函数类型的问题
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
时,这强制len
是Int
类型。由于需要更具体的类型,因此您声明的内容将引发错误。这可以通过更改类型签名来解决。
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
我正在开发一个用 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
时,这强制len
是Int
类型。由于需要更具体的类型,因此您声明的内容将引发错误。这可以通过更改类型签名来解决。
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