我正在学习Haskell。我正在尝试创建一个函数,当遇到某个函数f的参数时,它会从列表中删除整数。
deleteif :: [Int] -> (Int -> Bool) -> [Int]
deleteif x f = if x == []
then []
else if head x == f
then deleteif((tail x) f)
else [head x] ++ deleteif((tail x) f)
我收到以下错误:
函数尾部应用于两个参数
'deleteif'适用于太少的参数
答案 0 :(得分:4)
问题是你没有使用括号来调用Haskell中的函数。所以你只需要使用
if f (head x)
then deleteif (tail x) f
else [head x] ++ deleteif (tail x) f
答案 1 :(得分:2)
问题出在deleteif((tail x) f)
变为deleteif (tail x f)
所以tail得到2个参数
然后deleteif a
所以deleteif获得1个参数
你想要deleteif (tail x) f
head x == f
你错了`f(头x)
您可以使用模式匹配,保护并使其更通用
deleteif :: [a] -> (a -> Bool) -> [a]
deleteif [] _ = []
deleteif (x:xs) f
| f x = deleteif xs f
| otherwise = x : deleteif xs f
答案 2 :(得分:2)
如上所述,deleteif((tail x) f)
被解析为deleteif (tail x f)
,这意味着tail
会应用于两个参数x
和f
,结果会然后作为deleteif
的单个参数传递。你想要的是deleteif (tail x) f
,它等同于(deleteif (tail x)) f
以及大多数语言 1 会写deleteif(tail x, f)
。
这个解析顺序最初可能看起来令人困惑,但事实证明它在实践中非常有用。该技术的通用名称为Currying。
deleteif (tail x f)
也可以写成deleteif $ tail x f
。deleteif (>4) [1,3,7,5,2,9,7]
来产生[7,5,9,7]
。这可以通过将函数 2 >
部分应用于4
来实现,只留下一个可用于过滤列表的单参数函数。 1 的确,这种风格在Haskell中也是可能的:只需将这些多参数函数的签名写为deleteif :: ([Int], Int->Bool) -> [Int]
。或者写uncurry deleteif (tail x, f)
。但是你最好习惯咖喱风格!
2 实际上,>
是一个中缀,它的行为有点不同 - 你可以将它部分地应用到任何一方,即你也可以写deleteif (4>) [1,3,7,5,2,9,7]
以获取[1,3,2]
。