考慮以下IO
代碼:IO單子例
ghci> let x = return 100 :: IO Int
ghci> :t do { a <- x; print a; return 500 }
do { a <- x; print a; return 500 } :: Num b => IO b
我的做記號/綁定的是,下面的簽名將被由編譯器執行的理解:
ghci> :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
在上述例子中,我的理解是:
x
有型號IO Int
print a
具有類型IO()
return 500
的類型爲Num b => IO b
這在我看來,IO()
不符合的類型,Num b => IO b
。據我所知,IO Int
不符合Num b => IO b
。
如果這個觀察是有效的,那麼爲什麼這個代碼編譯?每行必須不爲>>=
,符合m b
,其中m
等於IO,b
等於Num b => b
?
爲什麼'IO()'需要堅持類型?爲什麼不應該'IO Int'符合約束?請注意,do'block的desugared版本使用>> >> ='__and__'>>'。還要注意,中間類型對於這裏的結果類型並不重要,例如, 'f = const 3。單詞。儘管'words'的類型爲'String - > [String]',但是'show'的類型是'(顯示a,數字b)=> a - > b'「。 – Zeta