【问题标题】:Getting Multiline haskell function to work in ghci让 Multiline haskell 函数在 ghci 中工作
【发布时间】:2016-08-11 01:39:04
【问题描述】:

我创建了这个 haskell 函数来从列表中删除奇数,并在 ghci 中尝试。尽管我启用了多行模式并使用 4 个空格进行缩进,但我仍然收到以下错误。

Prelude> :set +m
Prelude> let removeOdds nums =
Prelude|     if null nums
Prelude|     then []
Prelude|     else
Prelude|         if (mod (head nums)/2) == 0
Prelude|         then (head nums) : (removeOdds(tail nums))
Prelude|         else removeOdds(tail nums)
Prelude| 

:11:5: 解析错误(可能是缩进不正确或括号不匹配)

我阅读了this 页面,了解常见的可混淆新手的做法,我将代码更改如下

Prelude> let removeOdds nums =
Prelude|     do if null nums
Prelude|         then []    
Prelude|         else 
Prelude|           do if mod((head nums)/2) == 0
Prelude|               then head nums: removeOdds(tail nums)   
Prelude|               else removeOdds(tail nums)
Prelude| 

<interactive>:47:5:
    parse error (possibly incorrect indentation or mismatched brackets)

现在我以一个新错误结束。看起来缩进在haskell中很难解决。

【问题讨论】:

  • 顺便说一句 - 在 ghci 中输入多行语句很痛苦。我通常将编辑器窗口与运行 ghci 的控制台窗口并排使用。使用 ghci program.hs 调用 ghci。在编辑器中更改后,使用:r 重新加载program.hs。还可以查看:e:set editor 命令。另请参阅 GHCi 手册中的Loading source files
  • 多行函数的一个常见来源是重新发明轮子:let removeOdds = filter even

标签: haskell ghci


【解决方案1】:

您的if 语句至少需要缩进一个空格:

Prelude> let removeOdds nums =
Prelude|      if null nums

Complete example:

Prelude> let removeOdds nums =
Prelude|      if null nums
Prelude|      then []
Prelude|      else
Prelude|          if (mod (head nums) 2) == 0
Prelude|          then (head nums) : (removeOdds(tail nums))
Prelude|          else removeOdds(tail nums)
Prelude|
Prelude>

【讨论】:

  • Prelude> mod (head [10,20,30])/2 :153:1:约束中的非类型变量参数:分数(a -> a)(使用 FlexibleContexts允许这样做)当检查“它”是否具有推断类型时,它::forall a。 (分数 (a -> a), 整数 a) => a -> a
【解决方案2】:

在定义多行函数时,我在 GHCi 中使用花括号。它们允许您像通常编写的那样粘贴一大块 Haskell 代码。

λ :{
| let
| -- type or paste here, e.g.,
| removeOdds :: Integral a => [a] -> [a]
| removeOdds nums =
|   if null nums
|   then []
|   else -- ...
| :}
λ removeOdds [1,2,3,4]
[2,4]

【讨论】:

    【解决方案3】:

    还需要注意的是,如果您不在 REPL 中,因此不需要 let,那么您就不需要那么多缩进:

    removeOdds nums =
      if null nums
      then []
      else
        if (mod (head nums) 2) == 0
        then (head nums) : (removeOdds(tail nums))
        else removeOdds(tail nums)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-27
      • 1970-01-01
      • 1970-01-01
      • 2011-08-12
      相关资源
      最近更新 更多