Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type of return in do block

I am trying to understand Monads in Haskell and during my countless experiments with code I have encountered this thing:

f2 = do   
  return "da"

and the fact that it doesnt want to compile with huge error regarding type. I think the only important part is this:

 No instance for (Monad m0) arising from a use of return'
The type variable `m0' is ambiguous  

So then I have changed my code to:

 f2 = do   
 return "da"  :: IO [Char]  

And it worked perfectly well. But when I have tried to mess up a bit and change the type to IO Int it was an error once again. So why the type is "ambiguous" when it actually isnt? Also when I will add something before return like:

f2 = do   
  putStrLn "das"  
  return 2

Then I dont have to specify the type of return. So can someone explain me what is going on really? Also why is return outputting "da" in the first case? Not da without ""?

like image 643
user3002996 Avatar asked Dec 03 '22 20:12

user3002996


1 Answers

First let's just point out that

do
  return a

Is exactly the same as

return a

Now, the problem is that return has the type

return :: Monad m => a -> m a

And when you have a declaration like

foo = bar

where foo has no arguments haskell makes it "monomorphic". The result of this is that Haskell can't guess what m is and won't generalize it so you need an explicit type signature. The most general one is

f2 :: Monad m => m String
f2 = return "das"

But you could also use IO or any other monad

f2 :: IO String

Finally, in your last example, since you're returning 2, you'd have to give a type signature that indicates you're returning some sort of number, like

 f2 :: IO Integer
like image 190
Daniel Gratzer Avatar answered Dec 23 '22 19:12

Daniel Gratzer