考虑此liftA2
功能:
liftA2 :: (Maybe a -> Maybe b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c
liftA2 f Nothing Nothing = Nothing
liftA2 f (Just x) Nothing = Nothing
liftA2 f Nothing (Just y) = Nothing
liftA2 f (Just x) (Just y) = f x y
这等效于liftA2
中的实际liftA2
功能,但专门用于Control.Applicative
。 (以及Maybe
中的liftM2
)
我正在寻找该功能的表亲,其工作方式如下:
Control.Monad
我知道的最接近的概念是mystery :: (Maybe a -> Maybe a -> Maybe a) -> Maybe a -> Maybe b -> Maybe c
mystery f Nothing Nothing = Nothing
mystery f (Just x) Nothing = Just x
mystery f Nothing (Just y) = Just y
mystery f (Just x) (Just y) = Just (f x y)
,但如果有两个,则是<|>
,而我宁愿传递一个函数来组合它们。
这个神秘函数叫什么?它对什么类型的类起作用?我可以用Google的哪些条款来了解更多信息?谢谢!
如果您愿意接受其他类型的签名,而是使用Semigroup实例而不是任意函数discards the second value,那么您正在寻找的是Data.Semigroup中的Option newtype:
f
对于任意函数,您可能需要一些专门用于Maybe的东西-我真的不明白它如何对任意Applicative或Alternative起作用。
如果我理解正确,您可能会对Prelude Data.Semigroup> Option Nothing <> Option Nothing
Option {getOption = Nothing}
Prelude Data.Semigroup> Option (Just [1]) <> Option Nothing
Option {getOption = Just [1]}
Prelude Data.Semigroup> Option Nothing <> Option (Just [2])
Option {getOption = Just [2]}
Prelude Data.Semigroup> Option (Just [1]) <> Option (Just [2])
Option {getOption = Just [1,2]}
中的Semialign
类感兴趣,该类提供了类似Data.Align
的操作,不会丢失丢失的元素:
Data.Align
您可以写
zip
由于class Functor f => Semialign f where
align :: f a -> f b -> f (These a b)
align = alignWith id
alignWith :: (These a b -> c) -> f a -> f b -> f c
alignWith f as bs = f <$> align as bs
是alignBasic :: Semialign f => (a -> a -> a) -> f a -> f a -> f a
alignBasic f = alignWith $ \case
This a -> a
That a -> a
These a1 a2 -> f a1 a2
-- or just
alignBasic f = alignWith (mergeThese f)
的实例,所以Maybe
可以在类型上使用
Semialign