我正在尝试创建一个对foldr
函数求值的Bool
函数,如果返回True
,则返回值为tail xs
。我打算仅在参数函数返回True
时才删除FIRST元素。是否有一种方法可以更改foldr
(我也可以使用map
和/或filter
)在tail
的情况下返回True
?>
这是我一直在使用的两个条件函数:
isNegative = (<0)
isPositive = (>0)
这是一个递归函数,用于检查函数中是否有任何True
语句,但它会删除发生True
的元素,而不仅仅是返回tail xs
:
filterFirst :: (a -> Bool) -> [a] -> [a]
filterFirst x xs = foldr condition (\x -> []) xs True
where
condition y ys True
| x y = y : ys True
| otherwise = ys False
condition y ys False = y : ys False
是否可以使用此功能,但将其更改为仅删除FIRST元素?还是我需要一种完全不同的方法?
filterFirst
应该返回:
filterFirst isNegative [1,2,(-3)]
[2,-3]
filterFirst isPositive [1,2,(-3)]
[2,-3]
实际返回:
filterFirst isPositive [1,2,(-3)]
[1,2]
因为当我只想删除整个列表中的FIRST元素时,它正在过滤True
的第一个实例。
我必须保持函数定义相同,并且可以使用库函数,但只能通过映射,过滤和折叠文件夹高阶函数来解决此问题。我一直在努力工作,感觉就像开始时一样迷茫。
答案 0 :(得分:0)
我们应该能够清楚地陈述我们的问题,而不必依靠输入/输出示例。您没有明确的问题陈述,所以让我们从这里开始。这是我要陈述的方式:
filterFirst
包含一个谓词和一个列表。如果列表的 any 元素与谓词匹配,则返回列表的尾部,否则返回输入列表。输入列表为空时,返回空列表。
对于我们刚刚描述的函数来说,这不是一个好名字,但是我们将保留它。
这是一个让您入门的框架:
filterFirst p [] = [] -- "When the input list is empty, return the empty list."
filterFirst p l@(_:xs) =
if all p l
then xs -- "return the tail of the list"
else l -- "...otherwise return the input list"
all :: -- type left as an exercise
all p l =
-- try using `foldr` with `&&` here.
-- Then if you have time see if you can get it to return `False` on an infinite list.
-- if you get stuck, try using `filter`, `map`, `==` and `length` to implement this.