GHCi中的多行命令

R71*_*R71 119 haskell ghci

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

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

addTwo :: Int -> Int -> Int
addTwo x y = x + y
Run Code Online (Sandbox Code Playgroud)

但是当我进入ghci时,我会遇到错误.

我也尝试将代码放在里面:{ ... :},但它们也不适用于这个例子,因为这只是将行追加到一行,但不应该是这样.

我使用的是WinGHCi,版本2011.2.0.1

Nic*_* Wu 166

大多数情况下,您可以依靠类型推断来为您制作签名.在您的示例中,以下内容就足够了:

Prelude> let addTwo x y = x + y
Run Code Online (Sandbox Code Playgroud)

如果您确实需要带有类型签名的定义,或者您的定义跨越多行,则可以在ghci中执行此操作:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y 
Prelude| :}
Prelude> addTwo 4 7
11
Run Code Online (Sandbox Code Playgroud)

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

Prelude> let addTwo :: Int -> Int -> Int ; addTwo x y = x + y
Run Code Online (Sandbox Code Playgroud)

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

  • @Rog`let`开始一个块; 块中的条目按缩进分组; 并且块中的第一个非空白字符设置它们被分组的缩进.由于上面"let"块中的第一个非空白字符是"addTwo"的"a",所以块中的所有行都必须与"a"一样深. (8认同)

小智 108

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

Prelude> :set +m
Prelude> let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| 
Prelude> addTwo 1 3
4
Run Code Online (Sandbox Code Playgroud)

繁荣.


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

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

  • 如此简单,但并不明显.我想对第1页上没有告诉我的那本书感到尖叫! (5认同)
  • 在 Linux shell 中,`echo ':set +m' >> ~/.ghci` 使这个设置持久化。 (3认同)

Ste*_*ans 13

用途let:

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5
Run Code Online (Sandbox Code Playgroud)


dav*_*idA 7

为了扩展Aaron Hall 的答案let,至少在 GHCi 8.4.4 版本中,如果使用该样式,则不需要使用类型声明:{ :}。这意味着您不必担心在每个后续行上添加 4 个空格的缩进来说明let,从而使较长的函数更容易键入,或者在许多情况下,复制粘贴(因为原始源可能会赢) t 有正确的缩进):

\n\n
\xce\xbb: :{\n | addTwo :: Int -> Int -> Int\n | addTwo x y = x + y\n | :}\n\xce\xbb: addTwo 1 2\n3\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新

\n\n

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

\n\n

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

\n\n
class Box a where\n  mkBox :: a -> Boxes.Box\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n


Aar*_*all 5

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

所以这应该适合你:

?: addTwo x y = x + y
?: addTwo 1 2
3
?: :t addTwo
addTwo :: Num a => a -> a -> a
Run Code Online (Sandbox Code Playgroud)

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

?: addTwo 2.0 1.0
3.0
Run Code Online (Sandbox Code Playgroud)

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

?: let addTwo :: Int -> Int -> Int
 |     addTwo x y = x + y
 | 
?: addTwo 1 2
3
Run Code Online (Sandbox Code Playgroud)

但是,如果您尝试传递除 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
Run Code Online (Sandbox Code Playgroud)