Type of return in do block

安稳与你 提交于 2019-12-01 22:32:06

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

This is known Monomorphism_restriction

Use signatures

f2 :: Monad m => m String
f2 = do   
  return "da"

or use language extension:

{-# LANGUAGE NoMonomorphismRestriction #-}
f2 = do   
  return "da"

to get valid code

When learning about monads it's helpful to expand them out manually yourself, for instance the simple example:

test0 :: IO String
test0 = do
  a <- getLine
  putStrLn a
  return a

If we enable the language extension {-# LANGUAGE ScopedTypeVariables #-} then we can annotate each of the lines in the monad with it's explicit type which will show the type of the return block.

{-# LANGUAGE ScopedTypeVariables #-}

test1 :: IO String
test1 = do
  a <- getLine             :: IO String
  putStrLn a               :: IO ()
  return a                 :: IO String

We can also annotate the explicit type of the left hand side pattern matching which "extracts" from the monad context on the right hand side.

test2 :: IO String
test2 = do
  (a :: String) <- getLine  :: IO String
  (() :: ()) <- putStrLn a  :: IO ()
  return a                  :: IO String

We can even expand out the do-notation into its constituting parts:

test3 :: IO String
test3 = getLine >>=
        (\a -> putStrLn a >>=
        \() -> return a)

Hope that helps build your monad intuition.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!