在'case of'块中,绑定如何掩盖现有的绑定?

mkU*_*tra 5 haskell scope let shadowing letrec

我不得不从提取用户名和电子邮件EitherAuthResponse

我使用case of它的构造:

  let (uname, uemail) =
        case getUserResponseJSON creds of
          Right (GoogleUserResponse uname uemail) -> (uname, uemail)
          _ -> ("", "")    
Run Code Online (Sandbox Code Playgroud)

但我对uname和都有此警告uemail

    This binding for ‘uname’ shadows the existing binding
      bound at src/Foundation.hs:240:12
    |
242 |               Right (GoogleUserResponse uname uemail) -> (uname, uemail)
    |  
Run Code Online (Sandbox Code Playgroud)

我希望这let (uname, uemail)超出了范围case of

case如果unameuemail尚未定义,如何从块中获得此警告?

Wil*_*ess 6

Haskell的let实际上是letrec

在中let x = x in ...x右侧的是指x左侧。

的范围xyz

    let 
       x = ...
       y = ...
       z = ...
    in ...
Run Code Online (Sandbox Code Playgroud)

是用表示的所有代码区域...


Wil*_*sem 5

如果uname和uemail仍未定义,如何从大小写块中发出此警告?

这些是在之外的范围内定义的case,两个变量分别名为unameuemail。Haskell编译器可以“ 打结 ”。以下面的表达式为例,其中我们定义了一个无限的列表:

ones :: [Int]
ones = x
    where x = 1 : x
Run Code Online (Sandbox Code Playgroud)

因此,我们在这里定义一个看起来像这样的列表:

+-------+
|  (:)  |<,
+---+---+ |
| o | o---'
+-|-+---+
  v
  1
Run Code Online (Sandbox Code Playgroud)

因此,您可以像在此处一样根据变量本身定义变量。您没有为变量分配值,而是声明了变量。此外,请注意,定义变量的顺序本身并不是执行操作的顺序。因此,可能(uname, uemail)永远不会进行评估,等等。