10049

Is there a name for this kind of lifting a function?

Question:

I wrote a Scala function:

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 }

Is there a name for this pattern? It is not quite an applicative functor due to cases 1 and 2. Feel free to answer with Haskell or Scala code.

Answer1:

On collection it is flatten + reduce:

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

Answer2:

I'm reminded of the Alternative type class in Haskell's Control.Applicative:

class Applicative f => Alternative f where empty :: f a (<|>) :: f a -> f a -> f a

A general version of your function for any instance of Alternative might look like this:

liftOrAlternative :: (Alternative f) => (a -> a -> a) -> f a -> f a -> f a liftOrAlternative f a b = f <$> a <*> b <|> a <|> b <hr />ghci> liftOrAlternative (+) (Just 1) Nothing Just 1 ghci> liftOrAlternative (+) (Just 1) (Just 2) Just 3 ghci> liftOrAlternative (+) Nothing Nothing Nothing <hr />

For Scala, I think the closest analogy to Alternative would be the ApplicativePlus type class from Scalaz.

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

I admit that liftOrAlternative is not a great name. After reading Twan van Laarhoven's answer, I think his suggestion of unionWith is much better at expressing what the function actually does.

Answer3:

This function is similar to the Haskell containers function

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

I think unionWith is a good name for it in general. The more usual applicative operator would be an intersectionWith (aka. zipWith).

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

Answer4:

In Haskell, there is something similar called <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v%3aliftM2" rel="nofollow">liftM2</a>.

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

Recommend

  • reflect.Set slice-of-structs value to a struct, without type assertion (because it's unknown)
  • How can I merge several hashes into one hash in Perl?
  • Savon create matched XML pattern
  • mongodb DAO sets all attributes to null before save()
  • laravel view with a variable
  • Issues-parsing data to the php and jsons
  • xterm dump of full scrollable window content
  • Compiler agnostic runtime type information?
  • Searching IMAP inbox for messages from a specefic sender and use of wild cards?
  • jQuery on select show div
  • Does Go allow specification of an interface for a map with particular key type?
  • XML file with DTD displays fine in web browser after invalid change
  • in r combine a list of lists into one list
  • Push array into array on ruby by just one level
  • How to get the probabilities of classes in Spark Naive Bayes classifier?
  • turn two nested associative arrays into one flat array?
  • How to insert an Image in WORD after a bookmark using OpenXML
  • Hadoop shuffle uses which protocol?
  • finding greatest prime factor using recursion in c
  • How to get the index of element in the List in c#
  • Imageloader not loading image on real device
  • command line of process by name
  • Primefaces lazy datascroller calling load twice
  • Where these are stored?
  • abstracting over a collection
  • How can I tell a form not to dispose a particular control when it closes?
  • php design question - will a Helper help here?
  • retrieve vertices with no linked edge in arangodb
  • AngularJs get employee from factory
  • Acquiring multiple attributes from .xml file in c#
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Turn off referential integrity in Derby? is it possible?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Linking SubReports Without LinkChild/LinkMaster
  • Authorize attributes not working in MVC 4
  • How can I remove ASP.NET Designer.cs files?
  • Add sale price programmatically to product variations
  • Unable to use reactive element in my shiny app
  • java string with new operator and a literal
  • How do I use LINQ to get all the Items that have a particular SubItem?