首页 文章

如何在多行中定义ghci中的函数?

提问于
浏览
142

我正在尝试定义任何跨越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 `|'

我也试图使用 :{:} 命令,但我没有做得太远:

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

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

5 回答

  • 7

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

    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) }
    
  • 52

    GHCi现在具有多线输入模式,启用:set m . 例如,

    Prelude> :set +m
    Prelude> let fac 0 = 1
    Prelude|     fac n = n * fac (n-1)
    Prelude|
    Prelude> fac 10
    3628800
    
  • 17

    丹是正确的,但 :{:} 必须各自出现在他们自己的行上:

    > :{ 
    > 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 ()
    

    只有从文件中粘贴定义(缩进可能会发生变化)时,这才真正重要 .

  • 228

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

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

  • 115

    如果您不想仅为 :{:} 升级GHC,则需要在一行中全部写入:

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

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

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

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

相关问题