读完 Haskell 书籍后,我有点困惑(或者我只是忘记了)如何从 IO 域获取值,进入“Haskell 世界”来解析它,如下所示:
fGetSeq = do
input <- sequence [getLine, getLine, getLine]
fTest input
mapM_ print input
fTest = map (read :: String -> Int)
显然编译器会提示。 无法将 [] 与 IO 匹配
。是否有一个简单的经验法则可以在“世界”之间传递值,或者这只是我省略类型标志的错?
最佳答案
关于do
的事情符号是,其中的每个单子(monad) Action 值(<-
右侧的值,或在它们自己的行上)必须属于同一个 monad。这是
do {
x <- ma ; -- ma :: m a x :: a
y <- mb ; -- mb :: m b y :: b ( with the same m! )
return (foo x y) -- foo x y :: c return (foo x y) :: m c
} -- :: m c
现在,从sequence [getLine, getLine, getLine] :: IO [String]
开始,这意味着您的 do
block 属于 IO
。
但是当你获得这些值时,你可以根据自己的权利对待它们:
fGetSeq :: IO ()
fGetSeq = do
inputs <- sequence [getLine, getLine, getLine] -- inputs :: [String]
let vals = fTest inputs
mapM_ print vals
fTest :: [String] -> [Int]
fTest = map (read :: String -> Int)
-- or just
fGetSeq1 = do
inputs <- sequence [getLine, getLine, getLine]
mapM_ print ( fTest inputs )
-- or
fGetSeq2 = do { vals <- fTest <$> sequence [getLine, getLine, getLine] ;
mapM_ print vals } -- vals :: [Int]
-- or even (with redundant parens for clarity)
fGetSeq3 = mapM_ print =<< ( fTest <$> sequence [getLine, getLine, getLine] )
-- = mapM_ print . fTest =<< sequence [getLine, getLine, getLine]
Monad 的本质是在潜在不纯粹的“有效”计算之间分层纯粹的“Haskell 世界”计算。
所以我们已经进入了纯粹的 Haskell 世界,在 <-
的左侧。 。再次,inputs :: [String]
。纯粹的值(value)。
关于Haskell 从 IO 域获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52125583/