如何使用遍历删除列表中的特定值构造函数

问题描述 投票:0回答:1
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
,我就可以删除它们,修改它们(结束),更改它们(设置)

谢谢你!

haskell haskell-lens
1个回答
0
投票

无法使用

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)
© www.soinside.com 2019 - 2024. All rights reserved.