data Fruit = Apple Int
| Banana Color Int
data Color = Red
| Green
let basket = [Apple 3,Banana Red 30,Apple 6]
目标是仅保留
Banana
如何删除列表中的所有 Apple {}
basket
?使用遍历(https://hackage.haskell.org/package/lens-5.3.2/docs/Control-Lens-Traversal.html)?
一旦构建了
traversal
,我就可以删除它们,修改它们(结束),更改它们(设置)
谢谢你!
无法使用
Traversal
来完成。来自 base的
traverse
和来自 lens 的遍历都不允许这样做。
原因是遍历有一个重要的特性,即它们不会改变容器的整体“形状”。他们无法添加或删除元素。正如 Traversable
的
docs所说:
表示数据结构的函子可以转换为相同形状的结构
确实,
lens
文档说遍历可以让您“专注于”结构的某些元素。但这意味着您可以设置这些元素,或修改它们。您无法删除它们。
如果您正在为允许过滤操作的容器寻找类似于
Traversable
的类,可以使用 witherable包中的
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)