GHCi 中的多行命令

发布于 2024-12-20 11:54:11 字数 431 浏览 2 评论 0原文

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

以下两行代码在文件中工作:

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

I am having problem in entering multi-line commands in ghci.

The following 2-line code works from a file:

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

But when I enter in ghci, I get an error:

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

I also tried putting the code inside :{ ... :}, but they are also not working for this example, because this is just appending the lines into one line, which should not be the case.

I am using WinGHCi, version 2011.2.0.1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

予囚 2024-12-27 11:54:11

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

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 交互的更多信息的部分文档。

Most of the time, you can rely on type inference to work out a signature for you. In your example, the following is sufficient:

Prelude> let addTwo x y = x + y

If you really want a definition with a type signature, or your definition spans over multiple lines, you can do this in ghci:

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

Note that you can also squeeze this onto one line:

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

You can find out more about interacting with ghci on the Interactive evaluation at the prompt section of the documentation.

懷念過去 2024-12-27 11:54:11

通过启动 GHCI 并输入 :set +m:

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

Boom 来解决此问题。


这里发生了什么(我主要是在和交谈,你在学习学习 Haskell< 的同时通过谷歌搜索寻求帮助< /a>) 的原因是 GHCI 是一个交互式环境,您可以在其中动态更改函数名称的绑定。您必须将函数定义包装在 let 块中,以便 Haskell 知道您将要定义某些内容。 :set +m 是多行 :{ code :} 结构的简写。

空格在块中也很重要,因此您必须在类型定义之后将函数定义缩进四个空格,以考虑到 let 中的四个空格。

Solve this problem by firing up GHCI and typing :set +m:

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

Boom.


What's going on here (and I'm talking mostly to you, person googling for help while working your way through Learn You A Haskell) is that GHCI is an interactive environment where you're changing bindings of function names on the fly. You have to wrap your function definitions in a let block, so that Haskell knows that you're about to define something. The :set +m stuff is shorthand for the multiline :{ code :} construct.

Whitespace is also significant in blocks, so you have to indent your function definition after your type definition by four spaces to account for the four spaces in let.

迷迭香的记忆 2024-12-27 11:54:11

使用let

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5

Use let:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5
嗫嚅 2024-12-27 11:54:11

要扩展 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 on它自己的,按 Enter 键,然后粘贴不带任何定义的定义需要缩进。

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

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

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

To expand on Aaron Hall's answer, in version GHCi 8.4.4 at least, you don't need to use let with type declarations if you use the :{ :} style. This means you don't have to worry about adding the 4-space indentation on every subsequent line to account for let, making longer functions much easier to type, or in many cases, copy-paste (since the original source likely won't have the correct indentation):

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

Update

As an alternative you can turn on multi-line input mode with :set +m, then type let on its own, hit Enter, then paste definitions with no indentation required.

However this doesn't seem to work with some code blocks, such as:

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

But the :{, :} technique does.

笑,眼淚并存 2024-12-27 11:54:11

GHCI 版本 8.0.1< /a>, 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

但是,如果您尝试传递除 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

As of GHCI version 8.0.1, let is no longer required to define functions on the REPL.

So this should work fine for you:

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

Haskell's type-inference provides generalized typing that works for floats as well:

λ: addTwo 2.0 1.0
3.0

If you must provide your own typing, it seems you'll need to use let combined with multiline input (use :set +m to enable multiline input in GHCI):

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

But you'll get errors if you try to pass anything but an Int because of your non-polymorphic typing:

λ: 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文