
On Tue, Nov 2, 2010 at 2:11 PM, Brandon Moore
From: Max Cantor
Sent: Tue, November 2, 2010 7:58:49 AM FYI,
I implemented an error monad using this church-encoded either instead of the conventional either. my thought was that since you skip the conditional at each bind call you'd get better performance. I was quite mistaken.
That's surprising, I think LogicT gains significant performance from that sort of CPS conversion.
Was your code like this?
newtype ErrorC e a = ErrorC (runErrorC :: forall r . (e -> r) -> (a -> r) -> r)
instance Monad (ErrorC e) where return x = ErrorC (\fail succeed -> succeed x) ErrorC part1 >>= f = ErrorC (\fail succeed -> part1 fail (\a -> runErrorC (f a) fail succeed))
instance MonadError e (ErrorC e) where throwError e = ErrorC (\fail succeed -> fail e) catchError m handler = ErrorC (\fail succeed -> runErrorC m (\err -> runErrorC (handler err) fail succeed) succeed)
In a monad transformer, performing a CPS translation has the benefit of being able to implement bind, return and other effects without having to pass through operations on the wrapped monad. This could be part of the performance improvement you're seeing. Antoine