152

我在 ghci 中输入多行命令时遇到问题。

以下 2 行代码适用于文件:

addTwo :: Int -> Int -> Int
addTwo x y = x + y

但是当我输入 ghci 时,我得到一个错误:

<interactive>:1:1: error:
    Variable not in scope: addTwo :: Int -> Int -> Int

我也尝试将代码放入其中:{ ... :},但它们也不适用于此示例,因为这只是将行附加到一行中,情况不应该如此。

我正在使用 WinGHCi,版本 2011.2.0.1

4

5 回答 5

201

大多数时候,您可以依靠类型推断来为您制定签名。在您的示例中,以下内容就足够了:

Prelude> let addTwo x y = x + y

如果你真的想要一个带有类型签名的定义,或者你的定义跨越多行,你可以在 ghci 中这样做:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y 
Prelude| :}
Prelude> addTwo 4 7
11

请注意,您也可以将其压缩到一行:

Prelude> let addTwo :: Int -> Int -> Int ; addTwo x y = x + y

您可以在文档提示部分的交互式评估中找到有关与 ghci 交互的更多信息。

于 2011-12-09T08:52:34.547 回答
137

通过启动 GHCI 并键入以下内容来解决此问题:set +m

Prelude> :set +m
Prelude> let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| 
Prelude> addTwo 1 3
4

繁荣。


这里发生的事情(我主要是在与交谈,在通过Learn You A Haskell工作时正在谷歌搜索寻求帮助的人)是 GHCI 是一个交互式环境,您可以在其中动态更改函数名称的绑定。您必须将函数定义包装在一个let块中,以便 Haskell 知道您将要定义一些东西。这些:set +m东西是多行:{ 代码 :}结构的简写。

空格在块中也很重要,因此您必须在类型定义之后将函数定义缩进四个空格,以说明let.

于 2012-11-12T09:52:39.490 回答
15

使用let

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5
于 2011-12-09T08:54:29.040 回答
5

GHCI 版本 8.0.1 开始let不再需要在 REPL 上定义函数。

所以这对你来说应该很好:

λ: addTwo x y = x + y
λ: addTwo 1 2
3
λ: :t addTwo
addTwo :: Num a => a -> a -> a

Haskell 的类型推断提供了适用于浮点数的通用类型:

λ: addTwo 2.0 1.0
3.0

如果您必须提供自己的输入,您似乎需要let与多行输入结合使用(用于:set +m在 GHCI 中启用多行输入):

λ: let addTwo :: Int -> Int -> Int
 |     addTwo x y = x + y
 | 
λ: addTwo 1 2
3

但是,如果您尝试传递除 an 以外的任何内容,您将得到错误,Int因为您的非多态类型:

λ: addTwo 2.0 1.0

<interactive>:34:8: error:
    • No instance for (Fractional Int) arising from the literal ‘2.0’
    • In the first argument of ‘addTwo’, namely ‘2.0’
      In the expression: addTwo 2.0 1.0
      In an equation for ‘it’: it = addTwo 2.0 1.0
于 2018-12-30T06:20:38.293 回答
4

为了扩展Aaron Hall 的答案,至少在 GHCi 8.4.4 版本中,如果您使用样式,则不需要使用let类型声明。:{ :}这意味着您不必担心在每个后续行上添加 4 空格缩进来let说明正确的缩进):

λ: :{
 | addTwo :: Int -> Int -> Int
 | addTwo x y = x + y
 | :}
λ: addTwo 1 2
3

更新

作为替代方案,您可以使用 开启多行输入模式:set +m,然后let自行键入,按 Enter,然后粘贴定义而无需缩进。

但是,这似乎不适用于某些代码块,例如:

class Box a where
  mkBox :: a -> Boxes.Box

但是:{,:}技术可以。

于 2020-05-12T02:24:33.337 回答