haskell - Haskell 中关于 if-then-else 缩进的奇怪错误

标签 haskell functional-programming indentation

我有以下代码:

foo :: Int -> [String] -> [(FilePath, Integer)] -> IO Int
foo _ [] _ = return 4
foo _ _ [] = return 5
foo n nameREs pretendentFilesWithSizes = do
  result <- (bar n (head nameREs) pretendentFilesWithSizes)
  if result == 0
  then return 0 --  <========================================== here is the error
  else foo n (tail nameREs) pretendentFilesWithSizes

我在上面的评论中收到一个错误,错误是:
aaa.hs:56:2:
    parse error (possibly incorrect indentation)

我正在使用 emacs,没有空格,我不明白我做错了什么。

最佳答案

这在 Wikibooks article 的“if -within- do ”部分中进行了解释。关于 Haskell 缩进。

问题在于 do -脱糖者,thenelse行看起来像新语句:

do { first thing
   ; if condition
   ; then foo
   ; else bar
   ; third thing }

缩进 thenelse行将解决问题。

更新:由于这被标记为 beginner ,我还会注意到,在 Haskell 中,通常会认为以下内容更惯用:
foo :: Int -> [String] -> [(FilePath, Integer)] -> IO Int
foo _ [] _ = return 4
foo _ _ [] = return 5
foo n (r:rs) filesWithSizes = bar n r filesWithSizes >>= checkZero
  where
    checkZero :: Int -> IO Int
    checkZero 0 = return 0
    checkZero _ = foo n rs filesWithSizes

这与您的 foo 完全相同。 ,但它避免了 do糖并使用模式匹配而不是 headtailif-then-else控制结构。非正式地,>>=这里说“将 bar... 的输出从其 IO 包装器中取出并通过 checkZero 运行,返回结果”。

关于haskell - Haskell 中关于 if-then-else 缩进的奇怪错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2945600/

相关文章:

python - 如何使用函数式编程迭代并找到列表中五个连续数字的最大乘积?

python - 张量的 Tensorflow "map operation"?

vim - 使 vim 在循环时正确缩进管道

ruby - Emacs ruby​​ 模式缩进行为

haskell - 安装 leksah 的异常

haskell - 非 IO 单子(monad)是否有可能违反 Haskell 中的关联性?

Haskell:为什么它说我的函数类型是关闭的?

python - 使用 print() 时如何换行和缩进长行?

haskell - Haskell 中的 Monadic 类型检查器

haskell - 向类型类实例添加类约束