![](/img/trans.png)
[英]How does HOpenGL behave with regards to other threads and TChans in Haskell?
[英]How does the operator <- in haskell behave?
我了解(某種程度上)單子,並且理解運算符<-將從單子中提取值。
但是它如何與不同類型一起使用?
通常,我已經看到它用於從IO monad提取字符串。 但是在下面的示例代碼中,無法看到為什么它在主第三行中失敗,抱怨說它期望使用IO int類型? 編譯器如何推斷需要IO int?
另外,在multWithLog
方法中( <-
)有什么multWithLog
?
import Control.Monad.Trans.Writer.Lazy
main = do
putStrLn $ show $ logNumber 3 -- prints WriterT (Identity (3,["Got Number: 3"]))
putStrLn $ show $ multWithLog -- prints WriterT (Identity (3,["Got Number: 3"]))
_ <- logNumber 3 -- fails with Couldn't match type ‘WriterT [String] Data.Functor.Identity.Identity’ with ‘IO’
-- Expected type: IO Int
-- Actual type: Writer [String] Int
putStrLn "test"
logNumber :: Int -> Writer [String] Int
logNumber x = writer (x, ["Got Number: " ++ show x])
multWithLog :: Writer [String] Int
multWithLog = do
a <- logNumber 3
--b <- logNumber 5
return a
do
塊中的每個語句do
必須來自同一單子類型。
在
multWithLog = do
a <- logNumber 3
return a
我們有logNumber 3 :: Writer [String] Int
並return a :: (Monad m) => m Int
(它是多態的),因此整個類型都作為Writer [String] Int
(其中m = Writer [String]
,這是一個單子)。
在
main = do
putStrLn $ show $ logNumber 3
putStrLn $ show $ multWithLog
_ <- logNumber 3
putStrLn "test"
我們有putStrLn ... :: IO ()
和logNumber 3 :: Writer [String] Int
。 這是類型錯誤,因為Writer [String]
與IO
。
根本原因是do
塊只是>>=
和>>
調用的語法糖。 例如,您的main
意思是
main =
(putStrLn $ show $ logNumber 3) >>
(putStrLn $ show $ multWithLog) >>
logNumber 3 >>= \_ ->
putStrLn "test"
與
(>>) :: (Monad m) => m a -> m b -> m b
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
這要求類型m
始終保持相同。
注意諸如以下的措辭
從monad提取值
單聲道不包含“ a”值。 例如, Maybe
包含零或一個值。 列表( []
)包含多個值。 有關更多詳細信息,請參見此答案 。
例如,在列表的情況下, <-
運算符一次提取一個列表值。
使用do
表示法時,提取的所有值必須屬於同一Monad
。 在OP中,由於putStrLn
返回IO ()
值,因此編譯器推斷出該Monad
為IO
。
另一方面, logNumber
返回Writer [String] Int
值,盡管這也是Monad
實例,但它與IO
。 因此,該代碼不會鍵入檢查。
簡化事情。 這是兩個事實
Writer [String]
實際上是monad,因此Writer [String] Int
可以看作是m Int
do
塊中的每個動作都應在同一monad中發生。 在main
函數中,編譯器的推理如下:
IO
monad中工作,因為putStrLn ...
是IO ()
類型 _ <- logNumber 3
。 由於我在IO
monad中,因此logNumber 3
應該是IO WhatEver
logNumber 3
實際上是類型m Int
的單子值 m
是Writer [String]
monad,而不是IO
monad Writer [String] Int
不正確,應為IO Int
這就是IO Int
來源。 我只是想在這里進行教學。 查看@melpomene的答案以獲取完整說明
希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.