Haskell 哈斯克尔过滤器第一滤芯
我想删除第一个没有特定属性的元素。 例如,如果我的属性定义为Haskell 哈斯克尔过滤器第一滤芯,haskell,Haskell,我想删除第一个没有特定属性的元素。 例如,如果我的属性定义为 greaterOne :: Num a=>Ord a=>a->Bool greaterOne x = x > 1 那么函数filterFirst应该给我这个 filterFirst greaterOne [5,-6,-7,9,10] >> [5,-7,9,10] //removes first element that is not greater than one 这是我的尝试 filter
greaterOne :: Num a=>Ord a=>a->Bool
greaterOne x = x > 1
那么函数filterFirst
应该给我这个
filterFirst greaterOne [5,-6,-7,9,10]
>> [5,-7,9,10] //removes first element that is not greater than one
这是我的尝试
filterFirst :: (a->Bool)->[a]->[a]
filterFirst p [] = []
filterFirst p (x:y:xs)
|p x = filterFirst p xs
|otherwise = y:xs
有人能帮我吗?你可以为此滥用
deleteBy
> deleteBy (>) 1 [5, -6, -7, 9, 10]
[5,-7,9,10]
……更一般地说:
filterFirst p = deleteBy (const p) undefined
浏览您的尝试:将
[]
发送到[]
(这是正确的)。使用至少包含两个元素(x:y:xs
)的列表,您的函数测试x
,抛出x
和y
,并在测试通过时保持过滤(绝对不是您想要的),如果测试失败,则抛出x
,并停止(这是正确的)。包含单个元素的列表会出错,其他包含奇数个元素的列表也会出错(这既是错误的,也是正确答案的线索)
让我们一步一步地完成正确的实现。正如您所写,我们希望filterFirst
对a
进行一个谓词和一个a
列表,然后返回另一个a
列表:
filterFirst :: (a -> Bool) -> [a] -> [a]
谓词类型a->Bool
无法分解,但是[a]
可以:可以有空列表[]
和非空列表x:xs
,并且每个列表都应该有一个大小写:
filterFirst p [] = ...
filterFirst p (x:xs) = ...
在“基本情况”[]
中,没有任何内容需要过滤,因此我们希望它是[]
,这就是您编写的内容。由于此处未使用p
,因此在本例中,您可以将p
替换为。
:
filterFirst _ [] = []
但你不必这么做
我们想用x:xs
做什么取决于px
的值。如果px
成立,我们需要一个以x
开头的列表。此列表的尾部应该是xs
,但删除了第一个失败的元素。如果px
失败,我们想扔掉x
(第一个失败的元素)并保留xs
(第一个失败元素后面的列表)。因此:
这涵盖了所有的可能性,所以我们完成了
根据dfeuer的评论编辑。您可能需要类似as++bs中的
f p xs=let(as,(b:bs))=span p xs的内容,可能需要一些逻辑来处理没有元素匹配谓词,最后一个元素是第一个匹配的情况。filterFirst p(x:xs)=如果px然后x:filterFirstpxselse-xs
@user2407038,你为什么不回答这个问题呢?@user2407038我会选择这个作为最佳答案很好的答案,但我会写“ifpx
有效”而不是“ifpx==True
”。很多人会感到困惑,并使用==
来测试Bool
值,编写看起来很滑稽的代码。
filterFirst p (x:xs)
| p x = x:filterFirst p xs
| otherwise = xs