Elm中过滤List (Maybe a)的Nothing元素及类型判断问题
更简洁的Elm过滤Maybe列表方法 & 类型检查疑问解答
嘿,我完全懂你觉得原来那段foldr代码有点繁琐的感受!其实Elm里确实有更简洁的方式来处理过滤Maybe列表中Nothing的需求,而且还能顺便解答你关于类型检查的疑问。
一、简化过滤Maybe列表的实现
Elm的List模块自带了一个非常好用的函数——filterMap,它正好把过滤和映射两个操作合并在一起,处理Maybe类型简直是量身定做:
removeNothingFromList : List (Maybe a) -> List a removeNothingFromList = List.filterMap identity
解释一下:
identity是Elm核心库中的函数,作用就是返回输入本身(identity x = x)。filterMap的逻辑是:对列表中的每个元素应用传入的函数,如果函数返回Just val,就把val加入结果列表;如果返回Nothing,就直接跳过这个元素。- 这样一行代码就完成了你原来
foldr的所有功能,和JavaScript的filter写法一样简洁,还保持了Elm的类型安全性!
二、关于通用类型检查与按类型过滤
Elm是静态类型语言,和JavaScript的动态类型机制不同,所以没有“自动把任意类型转为布尔值”的隐式操作(这也是Elm避免很多运行时错误的原因)。不过我们可以针对具体场景实现类似的逻辑:
1. 针对Maybe类型的检查
如果你只是想检查一个Maybe值是否为Just,可以用核心库的isJust函数:
-- 过滤出所有Just元素(保留Maybe类型) List.filter isJust [ Just 1, Nothing, Just 2 ] -- 结果:[ Just 1, Just 2 ]
但如果要同时提取值,还是filterMap更高效,就像前面的例子那样。
2. 针对自定义类型的过滤
假设你有一个自定义类型:
type Pet = Dog String | Cat String
如果想过滤出所有Dog类型的元素,可以先写一个类型检查辅助函数:
isDog : Pet -> Bool isDog pet = case pet of Dog _ -> True Cat _ -> False
然后用List.filter过滤:
List.filter isDog [ Dog "旺财", Cat "咪咪", Dog "来福" ] -- 结果:[ Dog "旺财", Dog "来福" ]
如果还要提取Dog的名字,同样用filterMap:
getDogNames : List Pet -> List String getDogNames = List.filterMap (\pet -> case pet of Dog name -> Just name Cat _ -> Nothing )
3. 为什么没有通用的“类型转布尔”函数?
Elm的静态类型系统要求所有操作都是类型明确的,不同类型的“真假判断”逻辑差异很大(比如Maybe的Nothing算“假”,但自定义类型的分支没有统一的真假定义),所以核心库不会提供通用的类型转布尔函数。但你可以根据自己的需求,为特定类型编写对应的检查函数,这也更符合Elm的类型安全理念。
内容的提问来源于stack exchange,提问作者qonf
相关产品推荐
相关产品推荐

