【问题标题】:Haskell if then else parse error on input `else'Haskell if then else 解析输入'else'上的错误
【发布时间】:2014-01-09 06:23:10
【问题描述】:
if even 2 then 10 else 11 -- works fine

if even 2 then let t = 10 else let s = 11 -- _:27: parse error on input 'else'

if even 2 then 10 else let s = 11 -- _:34 parse error (possibly incorrect indentation or mismatched brackets)

因为假设我想用 [[p]] 编写类似这样的代码:

[ t | let e = [], 
      let o = p!!14, r <- [13,12..1], 
      if even r 
      then 
         let o = zipWith (+) (p!!r) (zipWith max e (drop 1 e))
             t = o
      else 
         e = zipWith (+) (p!!r) (zipWith max o (drop 1 o))
      t = e ]

在加载时报告错误。 . . _:33: 输入“else”时解析错误

【问题讨论】:

  • 你真的需要通过适当的 Haskell 入门教程。请不要假设 Haskell 和其他所有语言一样,就像你的 python 一样的列表推导。哦,还有一件事,欢迎来到 SO!

标签: haskell


【解决方案1】:

您似乎以命令的方式为不同分支中的绑定分配不同的值。这在 Haskell 中不起作用,您必须像这样在绑定的赋值中代替条件:

[ t | let e = [],
      let o = p!!14,
      r <- [13,12..1],
      let t = if even r
              then zipWith (+) (p!!r) (zipWith max e (drop 1 e))
              else zipWith (+) (p!!r) (zipWith max o (drop 1 o))
]

请注意,if 必须排队。它必须与= 在同一行开始,或者必须与下一行的= 处于相同或更高的缩进级别。

我注意到的另一件事是e 将永远是[],我想这不是本意。

【讨论】:

  • If/then/else 不需要缩进(它有关键字分隔每个部分,因此不需要缩进来确定部分的开始位置)。这里唯一对缩进敏感的结构是let,这确实意味着所有 if/then/else 必须在缩进多于t 的行上(无论行相对于彼此如何缩进)。 = 的位置与任何东西都无关。
【解决方案2】:

if 表达式中的 thenelse 部分应该在 Haskell 中返回相同的类型。

它的语法是这样的:

if <condition> then <true-value> else <false-value>\

在您的示例中,除非您计划在 if 条件本身中使用该变量,否则使用 let 是没有意义的。

LYAH book 很好地指出了 If 条件语言与命令式语言的区别:

Haskell 中的 if 语句和 if 语句的区别 命令式语言是 else 部分在 Haskell 中是强制性的。在 命令式语言,如果 条件不满足,但在 Haskell 中每个表达式和函数 必须返回一些东西。

【讨论】:

    【解决方案3】:
    then 
         let o = zipWith (+) (p!!r) (zipWith max e (drop 1 e))
             t = o
    

    “in”关键字必须在“let”表达式之后

    【讨论】:

    • 这是在列表理解中,这意味着您在 let 表达式之后没有 in。这样,它类似于do 块。
    猜你喜欢
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 2015-11-18
    • 2021-11-13
    • 2012-03-09
    相关资源
    最近更新 更多