【发布时间】:2021-04-17 11:08:35
【问题描述】:
考虑一下 Haskell 中的这两个函数:
replace_snd :: b -> Maybe (a, b) -> Maybe (a, b)
replace_snd y' (Just (x, y)) = Just (x, y')
replace_snd _ Nothing = Nothing
inject_snd :: Maybe b -> (a, b) -> Maybe (a, b)
inject_snd (Just b') (a, b) = Just (a, b')
inject_snd Nothing _ = Nothing
replace_snd 替换对的第二个元素,如果没有对则返回 Nothing:
> replace_snd 30 (Just (1, 2))
Just (1,30)
> replace_snd 30 Nothing
Nothing
inject_snd 替换第二个元素,如果没有替换则返回 Nothing:
> inject_snd (Just 30) (1, 2)
Just (1,30)
> inject_snd Nothing (1, 2)
Nothing
还要考虑它们的对称对应物replace_fst、inject_fst,它们作用于一对的第一个元素:
replace_fst :: a -> Maybe (a, b) -> Maybe (a, b)
replace_fst x' (Just (x, y)) = Just (x', y)
replace_fst _ Nothing = Nothing
inject_fst :: Maybe a -> (a, b) -> Maybe (a, b)
inject_fst (Just a') (a, b) = Just (a', b)
inject_fst Nothing _ = Nothing
我的问题是:这四个函数中哪一个可以写得更紧凑使用内置函数,如一元运算符?怎么做?
例如,我发现inject_snd 就是(mapM . const),因为Maybe 是Monad 而((,) a) 是Traversable:
> (mapM . const) (Just 30) (1, 2)
Just (1,30)
> (mapM . const) Nothing (1, 2)
Nothing
其他三个功能是否有类似的紧凑等价物?
【问题讨论】:
标签: haskell monads traversable