Search code examples
haskellcombinators

What is a Combinator in Haskell


In Real World Haskell, they describe combinators like this:

In Haskell, we refer to functions that take other functions as arguments and return new functions as combinators.

And then later they state that maybeIO function is a combinator and its type signature looks like this:

maybeIO :: IO a -> IO (Maybe a)

But all I can see is that maybeIO is a function that takes a value wrapped in IO monad and returns a value in IO monad. Then how does this function become a combinator ?


Solution

  • There are really 2 things that we could mean when we say combinator. The word is a bit overloaded.

    1. We usually mean a function which "combines" things. For example your function takes in an IO value and builds up a more complex value. Using these "combinators" we can combine and create new complex IO values from relatively few primitive functions to create IO values.

      For example, rather than creating a function which reads 10 files, we use mapM_ readFile. Here combinators are functions that we use to combine and build values

    2. The stricter computer sciencey term is a "function with no free variables". So

       -- The primitive combinators from a famous calculus, SKI calculus.
       id a         = a -- Not technically primitive, genApp const const
       const a b    = a
       genApp x y z = x z (y z)
      

      This is part of a grander field called "Combinatory logic" in which you seek to essentially eliminate free variables and replace it with combinators and a few primitive functions.

    TLDR: usually when we say combinator, we refer to a more general notion called the "combinator pattern" where we have a handful of primitive functions and a lot of user-defined functions to build up more complex values.