繁体   English   中英

GHCi 中的多行命令

[英]Multi-line commands in GHCi

我在 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

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

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

通过启动 GHCI 并输入:set +m来解决这个问题:

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

繁荣。


这是怎么回事(和我说主要是为了,人使用Google的帮助,同时通过工作的方式了解你的Haskell )是GHCI是你们在飞行中改变的函数名绑定一个互动的环境。 您必须将您的函数定义包装在一个let块中,以便 Haskell 知道您将要定义一些东西。 :set +m是多行:{ code :}结构的简写。

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

使用let

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
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

但是,如果由于您的非多态类型而尝试传递除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

为了扩展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

但是:{ , :}技术确实如此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM