Haskell中如何在数学表达式里使用Maybe数据类型?
如何在Haskell的数学表达式中使用Maybe数据类型?
报错原因
你写的代码里3 + (foo n ms)会报错,核心问题是类型不匹配:foo n ms返回的是Maybe Int类型,而+运算符要求左右两边都是同一种数值类型(属于Num类型类),但默认情况下Maybe Int并不是Num的实例,所以编译器无法推导如何对Maybe Int和Int执行加法。
不用fmap的实现方式
当然有,本质是手动处理Maybe的两种情况(Just x和Nothing),下面是几种常见写法:
1. 模式匹配(最直观)
直接对递归调用的结果做模式匹配,分别处理有值和无值的情况:
foo :: (Eq a) => a -> [a] -> Maybe Int foo _ [] = Nothing foo n (m:ms) | m == n = Just 5 -- 替换成你的实际条件逻辑 | otherwise = case foo n ms of Just x -> Just (x + 3) Nothing -> Nothing
2. Do语法(利用Monad特性)
借助Maybe的Monad实例,用do语法糖简化绑定逻辑:
foo :: (Eq a) => a -> [a] -> Maybe Int foo _ [] = Nothing foo n (m:ms) | m == n = Just 5 | otherwise = do x <- foo n ms return (x + 3)
3. 绑定运算符>>=
直接使用Monad的绑定操作符,把递归结果传递给匿名函数处理:
foo :: (Eq a) => a -> [a] -> Maybe Int foo _ [] = Nothing foo n (m:ms) | m == n = Just 5 | otherwise = foo n ms >>= \x -> Just (x + 3)
补充说明
其实fmap (+3) (foo n ms)是最简洁的写法,因为Maybe是Functor实例,fmap会自动帮你处理Just和Nothing的情况——本质和上面的模式匹配逻辑完全一致,只是用了更抽象的接口。如果只是单纯对Maybe内部的值做运算,fmap通常是最优选择。
内容的提问来源于stack exchange,提问作者kesarling
相关产品推荐
相关产品推荐

