Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 哈斯克尔过滤器第一滤芯_Haskell - Fatal编程技术网

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我会选择这个作为最佳答案很好的答案,但我会写“if
px
有效”而不是“if
px==True
”。很多人会感到困惑,并使用
==
来测试
Bool
值,编写看起来很滑稽的代码。
filterFirst p (x:xs)
    | p x       = x:filterFirst p xs
    | otherwise = xs