
On Sun, Jan 3, 2010 at 11:21 PM, Maciej Piechotka
On Sun, 2010-01-03 at 22:38 +0100, Francesco Guerrieri wrote:
My question is: how do you know in which monad you are computing at a given time?
'In which monad' question is the same as 'can type system be confused'.
I like this way of rephrasing it. Rahul's earlier answer led me to it, too.
Except for syntax sugar (do) monads are nothing special in Haskell. Not more special then Read or Show classes.
For example (for type system):
f :: [String] -> [String] f = map show . map read
main = interact (unlines . f . lines)
test.lhs:6:21: Ambiguous type variable `a' in the constraints: `Read a' arising from a use of `read' at test.lhs:6:21-24 `Show a' arising from a use of `show' at test.lhs:6:10-13 Probable fix: add a type signature that fixes these type variable(s)
Ok, I understand it this way: f takes a list of string, maps "read" to it and maps "show" (converting them to their string representation) to the resulting list. f never explicitly bothers with the type to which the strings were "read", since it shows them asap. BUT if the compiler is to pick an implementation of read, the type must be known.
With monad it is harder (as monad is one-way) but it is possible to do it:
extract $ liftM (+1) (return 0)
results in:
Ambiguous type variable `f' in the constraints: `Monad f' arising from a use of `liftM' at <interactive>:1:10-30 `Copointed f' arising from a use of `extract' at <interactive>:1:0-6 Probable fix: add a type signature that fixes these type variable(s)
We only know that we operate on some monad which is copointed. But we have no idea what is it. However in 99% of cases we don't have to.
(You man notice the signature of extract is - extract :: (Copointed f) => f a -> a so the problem is when we remove type [type does not occures on RHS of last ->])
Ok, you're losing me a bit with the "copointed f". Could you please clarify further the example? I assume that extract is the "inverse" of liftM. I have not yet found it and searching for "haskell extract monad" doesn't find a specific reference link. If extract "unlifts" a value out of a Monad I think that it cannot be defined for every monad (you cannot get out from the IO monad.... right?). In this sense you are first lifting and then unlifting like earlier you were first reading and then showing...? and so in principle you are "monad agnostic" but the type system is puzzled because it doesn't know to which monad you want to lift? Thanks, Francesco