学习Haskell为伟大的“函数中的语法”错误

时间:2014-01-20 04:21:16

标签: haskell

我是Haskell的新手,并且遵循以下教程:

http://learnyouahaskell.com/syntax-in-functions

本教程给出了以下示例:

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'

所以我在阅读本章时遇到了麻烦。

我做错了什么?

4 个答案:

答案 0 :(得分:13)

在GHCi中输入内容时,您可以使用let语句和几个分号或将其包含在:{:}中,这样做

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

或者

> :{
| 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]

答案 1 :(得分:5)

您无法直接将顶级定义写入GHCi。您需要将它们写入文件,然后通过将文件名作为参数(即ghci Bla.hs)或通过使用:load Bla.hs从GHCi中加载来将该文件加载到GHCi中。

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

答案 2 :(得分:3)

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

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

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

答案 3 :(得分:3)

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

第一行:lucky :: (Integral a) => a -> String正在为lucky提供类型签名 - 这就是::运算符的作用。当您在GHCi中键入该行时,它会查找符号lucky,但找不到符号。为GHCi中的函数分配显式类型是一种痛苦,因此其他答案中描述的写入文件然后加载工作流可能是您最好的选择。