Haskell 如何正确定义一个函数,如;任何;
研究Haskell,我试图编写一个函数Haskell 如何正确定义一个函数,如;任何;,haskell,Haskell,研究Haskell,我试图编写一个函数takeIf,给定一个条件,列表返回满足该条件的所有列表元素 所需输出的示例: takeIf (>0) [] --> [] takeIf (>0) [-1, 0, 1, 2] --> [1,2] 我试过这个定义: takeIf cond [] = [] takeIf cond (x:xs) = if (cond x) then x:(takeIf cond xs)
takeIf
,给定一个条件,列表返回满足该条件的所有列表元素
所需输出的示例:
takeIf (>0) [] --> []
takeIf (>0) [-1, 0, 1, 2] --> [1,2]
我试过这个定义:
takeIf cond [] = []
takeIf cond (x:xs) = if (cond x)
then x:(takeIf cond xs)
else []:(takeIf cond xs)
但它不起作用
我的第一个问题是:我有
:t takeIf --> ([a] -> Bool) -> [[a]] -> [[a]]
为什么??为什么不:
:t takeIf --> (a -> Bool) -> [a] -> [a]
我怎样才能让这个代码工作
这是我得到的错误:
如果有帮助,我正在使用ghci
[]:(takeIf cond xs)
在这里,您试图将[]作为新的第一个元素添加到takeIf cond xs
的结果中。由于[]
是一个列表,GHC由此推断takeIf cond xs
的结果必须是一个列表列表。由于takeIf的结果与其参数具有相同的类型,这意味着xs
也必须是列表列表。由于x
是xs
的一个元素,x
因此必须是一个列表
似乎您打算让[]:
表示“在列表中不添加任何内容”,但[]
不是什么,而是空列表<代码>[]:[],它不是给你[]
,而是给你[[]]
。同样地,[]:[1,2,3]
会给你[[],1,2,3]
——除了那不是很好的类型,所以它真正给你的是一个类型错误
如果您不想在列表中预先添加任何内容,请不要在列表中预先添加任何内容,即只需使用
someList
而不是[]:someList
,因为sepp2k比我快-我只想补充一点,您可能想看看它的源代码,它正是您尝试重新实现的函数。这是实际的来源
filter :: (a -> Bool) -> [a] -> [a]
filter _pred [] = []
filter pred (x:xs)
| pred x = x : filter pred xs
| otherwise = filter pred xs
另一种是褶皱,例如
filter' f = foldr go [] where
go x xs = if f x then x:xs else xs
请注意,
takeIf
在名称filter
下更为常见(并且已经定义)。是的,就像在Scheme中一样。我试图了解如何操作。好的,谢谢。按照您的指示,我还得到了另一种解决方案:使用[]++someList
。实际上我不知道,但您为什么要这样做[]+
。这是一种添加0的方法,编译器(希望)优化了它。我完全同意您的意见。这只是将空列表与另一个列表连接起来的方法,但您的建议要好得多。+1用于指出函数已经存在。但也要考虑到一种学习方式是编写现有功能的次优版本:Dthanks为+1,通过重写自己的IHOH学习是最有价值和令人恼火的事情之一,但之后/在过程中,你应该看看“亲”的人是如何实现你想要达到的东西的。这就是我想补充答案的原因。