<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
<div><font class="Apple-style-span" face="'Courier New'"><br></font></div><div><font class="Apple-style-span" face="'Courier New'"><span class="Apple-style-span" style="font-family: Verdana; "><font class="Apple-style-span" face="'Courier New'">I came across a type error that misled me for quite a while, because the expected and inferred types were backwards (from my point of view). &nbsp;A simplified example is below. &nbsp;Can someone explain how GHC's type checker creates the error message?</font></span></font></div><div><font class="Apple-style-span" face="'Courier New'"><br></font></div><font class="Apple-style-span" face="'Courier New'" style="text-indent: 0in !important; ">In this example, fun1 and fun2 are basically the same. &nbsp;The type error is because they try to run an IO () together with a Maybe ().</font><div><font class="Apple-style-span" face="'Courier New'"><br></font></div><div><font class="Apple-style-span" face="'Courier New'"><span class="Apple-style-span" style="font-family: Verdana; "><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt; import Control.Monad</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt;</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt; foo :: Maybe ()</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt; foo = return ()</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt;</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt; bar :: IO ()</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt; bar = return ()</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt;</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt; fun1 = let fooThen m = foo &gt;&gt; m</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt; &nbsp; &nbsp; &nbsp; &nbsp;in fooThen (bar &gt;&gt; undefined)</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt;</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt; fun2 = let fooThen m = foo &gt;&gt; m</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">&gt; &nbsp; &nbsp; &nbsp; &nbsp;in fooThen (do {bar; undefined})</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'"><br></font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">With ghc 6.10.4, both functions attribute the error message to `bar'. However, the expected and inferred monads are swapped.</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'"><br style="text-indent: 0in !important; "></font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">fun1 produces the error message:</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">Couldn't match expected type `Maybe a' against inferred type `IO ()'</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">In the first argument of `(&gt;&gt;=)', namely `bar'</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'"><br style="text-indent: 0in !important; "></font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">fun2 produces the error message:</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">Couldn't match expected type `IO ()' against inferred type `Maybe ()'</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">In a stmt of a 'do' expression: bar</font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'"><br></font></div><div style="text-indent: 0in !important; "><font class="Apple-style-span" face="'Courier New'">It's confusing because 'bar' is inferred to have type Maybe (), even though it's explicitly declared to be an IO ().</font></div></span></font></div>                                               <br /><hr />New Windows 7: Find the right PC for you. <a href='http://www.microsoft.com/windows/pc-scout/default.aspx?CBID=wl&ocid=PID24727::T:WLMTAGL:ON:WL:en-US:WWL_WIN_pcscout:102009' target='_new'>Learn more.</a></body>
</html>