haskelldemorgans-lawdot-operator

Haskell dot (.) operator in de Morgan's law implementation


In this question, the author has written an implementation of de Morgan's laws in Haskell. I understand the implementations of notAandnotB, and notAornotB, but I'm struggling to understand the implementation of notAorB which is:

notAorB :: (Either a b -> c) -> (a -> c, b -> c)
notAorB f = (f . Left, f . Right)

Could someone explain how the (f . Left, f . Right) part works? I've seen the . operator used before, but with three arguments, not two.

Thank you in advance.


Solution

  • Recall that the definition of the . operator is (f . g) x = f (g x), i.e. f . g = \x -> f (g x) (syntactically, it is a binary operator, it is just that Haskell’s syntax sugar permits the latter definition to be restated as the former). So, the definition you have can be rephrased as

    notAorB f = ((\x -> f (Left x)), (\y -> f (Right y)))
    

    (this can be done mechanically by Lambdabot on #haskell, tell him to @unpl ‹expr›), or more verbosely

    notAorB f = (lt, rt)
      where lt x = f (Left x)
            rt y = f (Right y)
    

    As always, try writing down the types. If (.) :: ∀ s t u. (t -> u) -> (s -> t) -> s -> u, f :: Either a b -> c, Left :: ∀ p q. p -> Either p q, then f . Left or (.) f Left :: a -> c, etc.