Haskell中如何筛选列表内含Apple值的Basket类型对象
Haskell过滤存放Apple的Basket对象实现
首先修正你给出的示例代码里的两处错误:
- 构造器拼写错误:类型定义里的构造器是
Basket,示例里误写为Baseket - 参数传递错误:
Basket构造器接收两个独立参数,第一个是Fruit枚举值,第二个是Int类型的计数,Apple本身是无参数的枚举值,不能像函数一样传入数字。正确的列表定义如下:
baskets = [Basket Apple 10, Basket Banana 2, Basket Apple 6]
Haskell里不需要像Python一样靠type/isinstance这类运行时类型判断函数做筛选,直接用模式匹配就能完成判断,这也是Haskell处理代数数据类型的标准写法。
首先写一个判断单个Basket是否存放Apple的函数:
isAppleBasket :: Basket -> Bool -- 模式匹配:只要Basket里第一个元素是Apple,不管数量是多少都返回True isAppleBasket (Basket Apple _) = True -- 其他所有情况(存Banana/Orange的Basket)都返回False isAppleBasket _ = False
之后直接调用列表的filter函数就能完成筛选:
appleBaskets = filter isAppleBasket baskets -- 执行结果:[Basket Apple 10, Basket Apple 6]
其他写法说明
如果你不想单独定义判断函数,也可以直接在filter里写lambda配合模式匹配:
-- 这种写法需要给Fruit派生Eq类型类才能用==比较 appleBaskets = filter (\(Basket fruit _) -> fruit == Apple) baskets
注意:要使用
==比较枚举值的话,定义数据类型时需要派生Eq实例,加上Show派生还能方便在交互环境直接打印结果,修改后的类型定义:data Fruit = Apple | Banana | Orange deriving (Eq, Show) data Basket = Basket Fruit Int deriving (Eq, Show)
相比直接用==判断,最开始的显式模式匹配写法不需要依赖Eq类型类,是更符合Haskell习惯的实现方式。
内容的提问来源于stack exchange,提问作者Shawn Zhang
相关产品推荐
相关产品推荐

