(read getLine) + (read getLine)

Tyson Whitehead twhitehead at gmail.com
Thu Mar 4 17:32:14 EST 2010


Consider what would happen if GHC optionally inserted a morphism on fexps (the 
expression at the head of an application) as it currently does with integer 
literals and optionally with string literals.  A standard function call

  f x y 

would windup as

  morph (morph f x) y

With the following basic classes

  -- Functor
  class F t where
      func :: (a -> b) -> t a -> t b

  -- Pointed
  class F t => P t where --
      pure :: a -> t a

  -- Applicative
  class P t => A t where
      apply :: t (a -> b) -> t a -> t b

  -- Monad
  class A t => M t where
      join :: t (t a) -> t a

we can define a standard set of morphisms

  -- Category
  class C a b where
      morph :: a -> b

  instance C (a -> b) (a -> b) where
      morph = id

  instance F t => C (a -> b) (t a -> t b) where
      morph = func

  instance P t => C (a -> b) (a -> t b) where
      morph f = func f . pure

  instance A t => C (t (a -> b)) (t a -> t b) where
      morph = apply

  instance A t => C (t (a -> b)) (a -> t b) where
      morph f = apply f . pure

  instance M t => C (t (a -> t b)) (t a -> t b) where
      morph f = join . apply f

  instance M t => C (t (a -> t b)) (a -> t b) where
      morph f = join . apply f . pure

  instance M t => C (a -> t b) (t a -> t b) where
      morph f = join . apply (pure f)

  instance M t => C (a -> t b) (a -> t b) where
      morph f = join . apply (pure f) . pure

If GHC could correctly pick between them (possibly if just tried them from 
most specific to least?), then we would get the following transformation

  (read getLine) + (read getLine)

  --> morph (morph (+) (morph read getLine)) (morph read getLine)

  --> apply (func (+) (func read getLine)) (func read getLine)

or, using the names in the standard library (include Control.Applicative),

  (<*>) (fmap (+) (fmap read getLine)) (fmap read getLine)

which does the right thing.

Anyway, thought I would throw it out there in case it could be made to work.

Cheers!  -Tyson


More information about the Glasgow-haskell-users mailing list