haskell - 转换具有两个以上 Action 的 "do"表示法以使用绑定(bind)函数

标签 haskell ghc monads

我知道下面的“do”符号的“bind”函数等价于getLine >>= \line -> putStrLn

do line <- getLine
   putStrLn line

但是下面的符号如何等同于绑定(bind)函数?
do line1 <- getLine
   putStrLn "enter second line"
   line2 <- getLine
   return (line1,line2)

最佳答案

我认为您正在尝试查看如何绑定(bind)“putStrLn”的结果。答案是 putStrLn 的类型:

putStrLn :: String -> IO ()

请记住,“()”是单位类型,它有一个值(也写成“()”)。所以你可以用完全相同的方式绑定(bind)它。但是由于您不使用它,因此您将其绑定(bind)到“无关”值:
getLine >>= \line1 ->
putStrLn "enter second line" >>= \_ ->
getline >>= \line2 ->
return (line1, line2)

碰巧的是,已经定义了一个忽略返回值“>>”的运算符。所以你可以把它重写为
getLine >>= \line1 ->
putStrLn "enter second line" >>
getline >>= \line2 ->
return (line1, line2)

我不确定您是否也想了解绑定(bind)运算符是如何以菊花链形式连接的。为了看到这一点,让我在上面的示例中放置隐式括号和额外的缩进:
getLine >>= (\line1 ->
   putStrLn "enter second line" >> (
      getline >>= (\line2 ->
         return (line1, line2))))

每个绑定(bind)运算符将左侧的值与右侧的函数链接起来。该函数由“do”子句中的所有其余行组成。因此,通过 lambda 绑定(bind)的变量(第一行中的“line1”)在整个子句其余部分的范围内。

关于haskell - 转换具有两个以上 Action 的 "do"表示法以使用绑定(bind)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3710991/

相关文章:

haskell - 这些线程是否永远被阻塞?

haskell - 了解 STG

编译用 haskell 和模板 haskell 编写的共享对象并将其与 c 中的 main 链接

haskell - 错误日志 monad 的高效实现

haskell - 定义一个函数时不使用任何语言扩展,但必须使用语言扩展来声明其类型?

haskell - Test.QuickCheck 的 Args 中的 maxSize 字段描述了什么?

haskell - .bib 文件中所有 BibTex 条目的列表,以生成 Hakyll 出版物列表?

haskell - ghci 段错误与简单的数学

haskell - 鉴于我知道实际数字,如何构建 ThreadId?

haskell - 如何映射和连接文件路径?