haskell - 'in' 关键字是怎么回事?

标签 haskell syntax

在 Haskell 中,为什么你不在 do-block 中使用 'in' 和 'let',但你必须不然呢?

例如,在下面有些人为的例子中:

afunc :: Int -> Int
afunc a = 
       let x = 9 in
       a * x

amfunc :: IO Int -> IO Int
amfunc a = do
       let x = 9
       a' <- a
       return (a' * x)

这是一个很容易记住的规则,但我就是不明白它的原因。

最佳答案

您正在提供表达式来定义 afuncamfunc . let 表达式和 do block 都是表达式。然而,虽然 let-expression 引入了一个新的绑定(bind),该绑定(bind)在 'in' 关键字之后给出的表达式的范围内,但 do-block 不是由表达式组成的:它是一个语句序列。 do-block 中有三种形式的语句:

  • 结果绑定(bind)到某个变量 x 的计算,如
    x <- getChar
    
  • 结果被忽略的计算,如
    putStrLn "hello"
    
  • 一个 let 语句,如
    let x = 3 + 5
    

  • let-statement 引入了一个新的绑定(bind),就像 let-expressions 一样。这个新绑定(bind)的范围扩展到 do-block 中的所有剩余语句。

    简而言之,let 表达式中“in”之后的是一个表达式,而 let 表达式之后的是一系列语句。我当然可以使用 let 表达式来表达对特定语句的计算,但是绑定(bind)的范围不会超出该语句到后面的语句。考虑:
    do putStrLn "hello"
       let x = 3 + 5 in putStrLn "eight"
       putStrLn (show x)
    

    上述代码在 GHC 中导致以下错误消息:
    Not in scope: `x'
    

    然而
    do putStrLn "hello"
       let x = 3 + 5
       putStrLn "eight"
       putStrLn (show x)
    

    工作正常。

    关于haskell - 'in' 关键字是怎么回事?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11674892/

    相关文章:

    haskell - 如何使用异常处理在 Haskell 中编写 "retryForever"函数?

    Java 被这种语法搞糊涂了

    c++ - 是否有将 vector 硬编码为参数的语法?

    syntax - 从函数的堆栈返回对 Path 的引用是如何工作的?

    replace - 如何使用 Ansible 替换文件中的字符?

    haskell - 元组是否使用特殊语法?

    performance - 概括斐波那契类型序列(性能)

    haskell - haskell 根据数据字段查找数据

    haskell - 无法读取点分隔的整数

    html - : 'selector.stuff1.stuff2' ? 这个 CSS 语法是什么意思