scala 这种提升函数有名字吗?

fykwrbwg  于 2022-11-09  发布在  Scala
关注(0)|答案(4)|浏览(128)

我编写了一个Scala函数:

def liftOrIdentity[T](f: (T, T) => T) = (a: Option[T], b: Option[T]) =>
    (a, b) match {
      case (Some(a), None) => Some(a)
      case (None, Some(b)) => Some(b)
      case (Some(a), Some(b)) => Some(f(a, b))
      case (None, None) => None
    }

这种图案有名字吗?由于案例1和案例2的原因,它并不是一个很实用的函数器。请随意使用Haskell或Scala代码进行回答。

mwg9r5ms

mwg9r5ms1#

集合时为flatten+reduce

List(a, b).flatten.reduceOption(f)
a ++ b reduceOption f // same result
ny6fqffe

ny6fqffe2#

我想起了Haskell的Control.Applicative中的Alternative类型类:

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,我认为最接近Alternative的类比是Scalaz中的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在表达函数的实际功能方面要好得多。

e0bqpujr

e0bqpujr3#

此函数类似于Haskell容器函数

Data.Map.unionWith :: (a -> a -> a) -> Map k a -> Map k a -> Map k a

总的来说,我认为Union With是一个很好的名字。更常用的应用运算符是intersectionWith(又名。zipWith)。

Data.Map.intersectionWith :: (a -> b -> c) -> Map k a -> Map k b -> Map k c
edqdpe6u

edqdpe6u4#

在Haskell中,有一种类似的东西被称为liftM2。

liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r

相关问题