Я понимаю (несколько) монады и понимаю, что оператор ‹- будет извлекать значение из монады.
Но как это работает с разными типами?
Как правило, я видел, как он используется для извлечения строк из монады IO. Но в приведенном ниже примере кода я не могу понять, почему он не работает в основной 3-й строке, жалуясь, что он ожидает тип ввода-вывода int? Как компилятор делает вывод, что требуется IO int?
И что он (<-
) делает в методе 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
должны быть типаMonad m => m _
для одного и того жеm
. - person Will Ness   schedule 04.09.2018do
блоке. поэтому попытка извлечения из разных монад в одном блокеdo
не работает. в этом была ваша проблема, а не в том, что вы написали выше. кроме того, не всегда вы упаковываете значение; иногда - как и в вашем коде - вы используете примитив данной монады, такой какputStrLn :: String -> IO ()
, который сам по себе возвращает монадическое значение действия. эта обертка не является хорошей метафорой. - person Will Ness   schedule 05.09.2018