data Fruit = Apple Int
| Banana Color Int
data Color = Red
| Green
let basket = [Apple 3,Banana Red 30,Apple 6]
目标是Banana
只保留
如何删除列表中的所有 Apple {} basket
?使用遍历()?
一旦traversal
建成,我就可以删除它们,修改它们(覆盖),更改它们(设置)
谢谢 !
8
最佳答案
1
无法使用Traversal
s 完成此操作。无论是traverse
从遍历都不允许这样做。
原因是遍历具有重要的属性,即它们不会改变容器的整体“形状”。它们不能添加或删除元素。正如所述Traversable
:
函子表示可以转换为相同形状结构的数据结构
文档确实lens
说遍历可以让你“关注”结构的某些元素。但这意味着你可以设置或修改这些元素。你无法删除它们。
如果您正在寻找Traversable
允许(可能有效的)过滤操作的容器类,那么可以从Filterable
包中找到。Witherable
但对于你来说,我只需做类似的事情
removeApples :: [Fruit] -> [Fruit]
removeApples = mapMaybe (\f -> case f of
Apple {} -> Nothing
other -> Just other)
removeApples2 :: [Fruit] -> [Fruit]
removeApples2 = foldMap (\f -> case f of
Apple {} -> []
other -> [other])
removeApples3 :: [Fruit] -> [Fruit]
removeApples3 fruits = do -- list monad
fruit <- fruits
case fruit of
Apple {} -> []
other -> [other]
removeApples4 :: [Fruit] -> [Fruit]
removeApples4 = filter (\f -> case f of
Apple {} -> False
other -> True)
2
-
有没有一种方法可以将
Apple
函数签名参数化,这样下次用户想要时它看起来是通用的remove
Banana
?这样可以避免再次重写几乎相同的函数(只需替换Apple
为Banana
)
– -
@ShawnZhang “镜头”包(也称为“光学”包)具有 的概念
Prism
。您可以为 sum 类型创建它们,并将它们用作某种“一流模式”来定义谓词函数,借助has
或 等组合器hasn't
。示例:
–
|
filter
功能。–
filter
只能过滤,但遍历才能modify
选择replace
。–
traversal
?标准traverse
功能根本无法过滤。–
–
–
|