'in'关键字是什么? [英] What's with the 'in' keyword?

查看:188
本文介绍了'in'关键字是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Haskell中,为什么不在'do'块中使用'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)



这个规则很容易记住,但我不明白其原因。

解决方案

您正在提供用于定义 afunc amfunc 的表达式。让 - 表达式和do-blocks都是表达式。但是,尽管let表达式引入了一个新的绑定,它围绕在'in'关键字后面给出的表达式,但do块并不是由表达式组成的:它是一系列语句。在do-block中有三种形式的语句:


  1. 一个计算结果被绑定到某个变量<$ c $在

      x < -  getChar 





    $ b $ > putStrLnhello


  2.   let x = 3 + 5 


let语句引入了一个新的绑定,就像let-expressions一样。这个新绑定的作用域覆盖了do-block中所有剩余的语句。



总之,let表达式中的'in'后面是一个表达式,而let表达式后面是一系列语句。当然,我可以使用let表达式来表达特定语句的计算,但是这个绑定的范围不会超出这个语句到后面的语句。考虑:

 做putStrLnhello
let x = 3 + 5 in putStrLneight
putStrLn(show x)

以上代码在GHC中会导致以下错误消息:

 不在范围内:`x'


$ b而
$ b $ pre $ 做putStrLnhello
let x = 3 + 5
putStrLn 八
putStrLn(显示x)

正常工作。


In Haskell, why do you not use 'in' with 'let' inside of a do-block, but you must otherwise?

For example, in the somewhat contrived examples below:

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)

It's an easy enough rule to remember, but I just don't understand the reason for it.

解决方案

You are providing expressions to define both afunc and amfunc. Let-expressions and do-blocks are both expressions. However, while a let-expression introduces a new binding that scopes around the expression given after the 'in' keyword, a do-block isn't made of expressions: it is a sequence of statements. There are three forms of statements in a do-block:

  1. a computation whose result is bound to some variable x, as in

    x <- getChar
    

  2. a computation whose result is ignored, as in

    putStrLn "hello"
    

  3. A let-statement, as in

    let x = 3 + 5
    

A let-statement introduces a new binding, just as let-expressions do. The scope of this new binding extends over all the remaining statements in the do-block.

In short, what comes after the 'in' in a let-expression is an expression, whereas what comes after a let expression is a sequence of statements. I can of course express a computation of a particular statement using a let-expression, but then the scope of the binding would not extend beyond that statement to statements that follow. Consider:

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

The above code causes the following error message in GHC:

Not in scope: `x'

whereas

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

works fine.

这篇关于'in'关键字是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆