我在输入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
答案 0 :(得分:157)
大多数情况下,您可以依靠类型推断来为您制作签名。在您的示例中,以下内容就足够了:
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
您可以在文档的Interactive evaluation at the prompt部分找到有关与ghci交互的更多信息。
答案 1 :(得分:100)
通过启动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
中的四个空格。
答案 2 :(得分:13)
使用let
:
Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude| addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5
答案 3 :(得分:2)
从GHCI version 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
答案 4 :(得分:2)
要至少在GHCi 8.4.4版的Aaron Hall's answer上进行扩展,如果您使用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
但是:{
,:}
技术确实有用。