组合 (a -> Maybe a) 和 (an -> a) 函数
Combining (a -> Maybe a) and (a -> a) functions
我有两个功能:
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 x = fmap g (f x)
或运营商版本:
h :: a -> Maybe a
h x = g <$> f x
因为你用 dot-operator 标记了这个问题:
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
注意(.)
和fmap g
的类型其实更通用:
(.) :: (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
的 return 类型不正确。
有
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
可以代替(.)
。
我有两个功能:
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 x = fmap g (f x)
或运营商版本:
h :: a -> Maybe a
h x = g <$> f x
因为你用 dot-operator 标记了这个问题:
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
注意(.)
和fmap g
的类型其实更通用:
(.) :: (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
的 return 类型不正确。
有
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
可以代替(.)
。