182

我正在尝试在 ghci 中定义任何跨越多行的简单函数,以以下为例:

let abs n | n >= 0 = n
          | otherwise = -n

到目前为止,我已经尝试在第一行之后按 Enter:

Prelude> let abs n | n >= 0 = n
Prelude>           | otherwise = -n
<interactive>:1:0: parse error on input `|'

我也尝试使用:{and:}命令,但我没有走远:

Prelude> :{
unknown command ':{'
use :? for help.

我在 Linux 上为 Haskell 98 使用 GHC Interactive 6.6 版,我缺少什么?

4

7 回答 7

284

GHCi 现在有一个多行输入模式,通过 :set +m 启用。例如,

Prelude> :set +m
Prelude> let fac 0 = 1
Prelude|     fac n = n * fac (n-1)
Prelude|
Prelude> fac 10
3628800
于 2013-11-05T20:43:21.570 回答
137

对于守卫(如您的示例),您可以将它们全部放在一条线上并且它可以工作(守卫不关心间距)

let abs n | n >= 0 = n | otherwise = -n

如果您想编写具有参数模式匹配的多个定义的函数,如下所示:

fact 0 = 1
fact n = n * fact (n-1)

然后您将使用带有分号的大括号分隔定义

let { fact 0 = 1 ; fact n = n * fact (n-1) }
于 2010-05-17T04:10:31.680 回答
69

Dan 是正确的,但每个人:{:}必须出现在自己的行中:

> :{ 
> let foo a b = a +
>           b
> :}
> :t foo
foo :: (Num a) => a -> a -> a

这也与布局规则交互,因此在使用 do-notation 时,显式使用大括号和分号可能更容易。例如,此定义失败:

> :{
| let prRev = do
|   inp <- getLine
|   putStrLn $ reverse inp
| :}
<interactive>:1:18:
    The last statement in a 'do' construct must be an expression

但它在添加大括号和分号时有效:

> :{
| let prRev = do {
|   inp <- getLine;
|   putStrLn $ reverse inp;
| }
| :}
> :t prRev
prRev :: IO ()

这只有在从文件中粘贴定义时才真正重要,因为缩进可能会改变。

于 2010-08-20T15:46:56.560 回答
20

它看起来像是一个非常新的功能:{:}您可能需要升级 GHC。

编辑:确认,见http://www.haskell.org/ghc/docs/6.8.2/html/users_guide/release-6-8-2.html

于 2010-05-17T00:24:49.557 回答
8

如果您不想只为:{and升级 GHC :},则需要将其全部写在一行上:

> let abs' n | n >= 0 = n | otherwise = -n

我不知道 Haskell 中有任何单个定义必须写在多行上。以上确实在 GHCi 中有效:

> :t abs'
abs' :: (Num a, Ord a) => a -> a

对于其他表达式,例如do块,您需要使用带有大括号和分号的非布局语法(呃)。

于 2010-05-17T00:39:55.137 回答
2

看起来像一次粘贴两行或对每个新行使用 control-enter 将它们保持在一起,至少在https://repl.it/languages/haskell。您会在第二行的开头看到 2 个点。或者把它放在一个文件中并 :load 文件 (:l main)。为什么 abs 不适用于负数?哦,你必须在数字周围加上括号。

   let abs n | n >= 0 = n 
..           | otherwise = -n
   abs (-1)
于 2020-07-14T13:50:22.633 回答
0

我在 macOS Catalina 10.15.2 上使用 GHCi,版本 8.2.1。以下是我如何将函数类型声明和守卫放在一起。请注意,左侧的垂直条用于 GHCi 多行。

λ: let abs' :: (Num a, Ord a) => a -> a
 |     abs' n | n >= 0 = n | otherwise = -n
 | 
λ: abs' 7
7
λ: abs' (-7)
7
于 2019-12-15T11:26:25.050 回答