(read getLine) + (read getLine)

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
participants (1)
-
Tyson Whitehead