我有两个功能:
f :: a -> Maybe a g :: a -> a
我想创建这样的功能:
h :: a -> Maybe a h x | isJust(f x) = Just (g $ fromJust(f x)) | otherwise = Nothing
我怎样才能以更优雅的方式做到这一点?
由于您使用点运算符标记了此问题:
h :: a -> Maybe a h = fmap g . f
有关解释:
f :: a -> Maybe a g :: a -> a fmap g :: Maybe a -> Maybe a (.) :: (Maybe a -> Maybe a) -> (a -> Maybe a) -> (a -> Maybe a) (.) (fmap g) :: (a -> Maybe a) -> (a -> Maybe a) fmap g . f :: (a -> Maybe a) h :: a -> Maybe a
请注意,(.)
's和fmap g
's类型实际上更通用:
(.) :: (b -> c) -> (a -> b) -> (a -> c) -- b in this case is Maybe a -- c in this case is Maybe a fmap g :: Functor f => f a -> f a -- f in this case is Maybe
但是,您也可以对结果进行模式匹配f
:
h x = case f x of Just k -> Just (g k) _ -> Nothing
请注意,您的原始示例甚至不会编译,因为g
返回类型不正确.
有
fmap2 :: (Functor g, Functor f) => (a -> b) -> g (f a) -> g (f b) fmap2 = fmap . fmap
这是一个有趣的方式:
h :: a -> Maybe a h = fmap2 g f
fmap2 g f ~> fmap (fmap g) f ~> fmap g . f ~> \x -> fmap g (f x)
该Functor ((->) r)
实例这里使用:fmap
可以用来代替(.)
.