Haskell 向你学习哈斯凯尔语,为你带来巨大的好处”;函数中的语法;错误

Haskell 向你学习哈斯凯尔语,为你带来巨大的好处”;函数中的语法;错误,haskell,Haskell,我是Haskell的新手,正在学习中给出的教程: 本教程给出了以下示例: lucky :: (Integral a) => a -> String lucky 7 = "LUCKY NUMBER SEVEN!" lucky x = "Sorry, you're out of luck, pal!" 但是,我打开了GHCI,当我键入第一行时,出现以下错误: <interactive>:231:1: Not in scope: `lucky' :231:1:不

我是Haskell的新手,正在学习中给出的教程:

本教程给出了以下示例:

lucky :: (Integral a) => a -> String  
lucky 7 = "LUCKY NUMBER SEVEN!"  
lucky x = "Sorry, you're out of luck, pal!" 
但是,我打开了GHCI,当我键入第一行时,出现以下错误:

<interactive>:231:1: Not in scope: `lucky'
:231:1:不在范围内:'lucky'
所以我很难理解这一章


我做错了什么?

您不能像这样将顶级定义直接写入GHCi。您需要将它们写入一个文件,然后通过将文件名作为参数传递(即
GHCi Bla.hs
)或使用
:load Bla.hs
从GHCi中加载文件,将其加载到GHCi中


在GHCi中,您只能像在
do
块中一样,使用
let
使用本地定义。

尝试从GHCi添加多行定义有点笨拙

<>有两个工作流程需要考虑。首先是使用您喜爱的文本编辑器(
Foo.hs
)创建一个新文件。将其加载到GHCi中,然后使用GHCi命令
:edit
$EDITOR
和repl之间来回循环


等效地,只需创建一个单独的文件,启动GHCi并在进行更改时使用
:load
:reload
加载它。

在GHCi中键入该文件时,您可以使用
let
语句和几个分号或将其包装在
:{
:}

> let lucky :: (Integral a) => a -> String; lucky 7 = "LUCKY NUMBER SEVEN!"; lucky x = "Sorry, you're out of luck, pal!"

您还可以使用
+m
标志将多行输入设置为默认值:

> :set +m
> let lucky :: (Integral a) => a -> String
|     lucky 7 = "LUCKY NUMBER SEVEN!"
|     lucky x = "Sorry, you're out of luck, pal!"
|
> mapM_ (putStrLn . lucky) [1..10]

LYAH在这方面有点不清楚,但你不能真正做到这一点。这实际上是GHCi和其他repl之间巨大差异的一个更大的症状,比如说通过运行
python
得到的repl。GHCi中的语法与在文件中编写代码的语法略有不同,因此您不能只是从文件中粘贴代码块,然后期望它们工作。这段代码就是一个例子


第一行:
lucky::(积分a)=>a->String
lucky
一个类型签名-这就是
操作符所做的。在GHCi中键入该行时,它会查找符号
lucky
,但找不到。为GHCi中的函数指定显式类型是一种痛苦,因此其他答案中描述的先写文件再加载工作流可能是您最好的选择。

谢谢,这比尝试让GHCi做它不打算做的事情感觉要好得多。我安装了Sublime Text,将代码放在那里,按下Ctrl-Shift-B,终于可以开始真正的Haskell编码了。
> :set +m
> let lucky :: (Integral a) => a -> String
|     lucky 7 = "LUCKY NUMBER SEVEN!"
|     lucky x = "Sorry, you're out of luck, pal!"
|
> mapM_ (putStrLn . lucky) [1..10]