我想起了Alternative
Haskell 中的类型类Control.Applicative
:
class Applicative f => Alternative f where
empty :: f a
(<|>) :: f a -> f a -> f a
任何实例的函数的通用版本Alternative
可能如下所示:
liftOrAlternative :: (Alternative f) => (a -> a -> a) -> f a -> f a -> f a
liftOrAlternative f a b = f <$> a <*> b <|> a <|> b
ghci> liftOrAlternative (+) (Just 1) Nothing
Just 1
ghci> liftOrAlternative (+) (Just 1) (Just 2)
Just 3
ghci> liftOrAlternative (+) Nothing Nothing
Nothing
对于 Scala,我认为最接近的类比是来自 ScalazAlternative
的类型类。ApplicativePlus
def liftOrAlternative[A, F[_]: ApplicativePlus](f: (A, A) => A)(a: F[A], b: F[A]): F[A] =
f.lift[F].apply(a, b) <+> a <+> b
我承认这liftOrAlternative
不是一个好名字。在阅读了 Twan van Laarhoven 的回答后,我认为他的建议unionWith
更好地表达了函数的实际作用。