Why is this function allowed:
-- function 1
myfunc :: String
myfunc = do
x <- (return True)
show x
and this is not:
-- function 2
myfunc :: String
myfunc = do
x <- getLine
show x
The compile error:
Couldn't match type `[]' with `IO'
Expected type: IO Char
Actual type: String
I get why function 2 shouldn't work, but why then thus function 1 work?
and why does this then work:
-- function 3
myfunc = do
x <- getLine
return (show x)
I get that it returns IO String then, but why is function 1 also not forced to do this?
In function1 the
doblock inmyfuncis working in the list monad, becauseStringis really just[Char]. In there,return Truejust creates[True]. When you dox <- return Truethat "extracts"Trueout of[True]and binds it tox. The next lineshow xconvertsTrueinto a String"True". which being the return value the compiler value expects to see, ends up working fine.Meanwhile in function2, the
doblock in myfunc is also working on the list monad (for the same reason,Stringbeing really[Char]) but calls ongetLinewhich is only available in theIOmonad. So unsurprisingly, this fails.-- EDIT 1
OP has added a function3
No this should not work for the same reason function2 fails.
-- EDIT 2
OP has updated function3 to fix a copy paste error.
This is mentioned in the comments, but for clarity sake, this works because, when the type information is unspecified, GHC makes it best inference and after seeing
getLine, it figures it’sIO Stringwhich does providegetLine.Note - I wrote this answer with as casual a tone as I could manage without being wrong with the intention of making it approachable to a beginner level.