(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