我正在尝试创建一个接受 Int
的函数( n
), 和列表 k
的 Int
s,并返回所有数字的总和 1 <= i <= n
, 可被列表 k
中的至少一个整数整除.
addl::Int -> [Int] -> Int
addl x [] = 0
addl x (y:ys) = if ((map [1..x] `mod` y) == 0)
then y + addl x ys
else 0 + addl x ys
这就是我得到的,但我收到了这条消息:
Couldn't match expected type `a0 -> b0' with actual type `[t0]'
In the first argument of `map', namely `[1 .. x]'
In the first argument of `mod', namely `map [1 .. x]'
In the first argument of `(==)', namely `(map [1 .. x] `mod` y)'
我想弄清楚,但还没有理解。 非常感谢所有帮助。
最佳答案
map
需要一个函数作为它的第一个参数,但您为它提供了一个列表。
错误信息就是这么说的。它表示表达式 ((map [1..x] `mod` y) == 0)
被解析为
(==) -- In the first argument of `(==)', namely `(map [1 .. x] `mod` y)'
mod -- In the first argument of `mod', namely `map [1 .. x]'
map [1..x] -- In the first argument of `map', namely `[1 .. x]'
y
0
-- Couldn't match expected type `a0 -> b0' with actual type `[t0]'
map
的类型是
Prelude> :t map
map :: (a -> b) -> [a] -> [b]
Prelude> :t [undefined]
[undefined] :: [a]
和(a1 -> b1)
和[a2]
不匹配。
与其在你的代码中混淆这两个 Action (过滤和求和),而不是混淆(你甚至在那里对错误的变量 y
求和),将过程模块化到第一次搜索更简单,并且只有这样,总结:
addl::Int -> [Int] -> Int
addl n ks = sum -- then, sum
[i | i <- [1..n], isDividedByAny i ks] -- first, search
where
isDividedByAny i ks =
any
[ rem i k == 0 | k <- ks]
这里我们使用 (a -> Bool) -> [a] -> Bool
类型的内置函数 any
(即它得到一个谓词函数,值列表,并返回一个 bool 值)。
请注意我在这里如何称呼您的 k
列表 ks
,表明它是一个“k”列表。这在 Haskell 中是惯用的。
关于list - 如何测试一个列表中的整数是否可以被另一个列表中的整数整除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26098313/