Haskell 从 IO 域获取值

标签 haskell io monads type-mismatch do-notation

读完 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/

相关文章:

haskell - 奇怪的存在类型

haskell - 为什么 Haskell 中的 main 函数没有任何参数?

haskell - 在 let 中使用 Monadic do 表示法,这可能吗?

php - 循环多次写入文件或创建巨大的字符串然后写入文件?

c# - 如何返回不包含目录路径的目录文件/文件夹?

haskell - 说明 Category、Monoid 和 Monad 的简单例子?

haskell - 理解 State Monad 中的 state 参数

Haskell: monadic takeWhile?

F# 自定义计算工作流程

c++ - 在C++中向文件写入和加载大数组