存疑的Haskell列表推导式:此类代码是否应被编译器接受?
Haskell列表推导式的行为疑问
comp5 :: [ Either Int Int ] comp5 = [ Right x | {- Just y <- Just 2, -} let x = 5, y <- [x, undefined] ] -- ^^ 被拒绝:右值必须是列表,`let`被接受
- 被注释的
Just y <- Just 2因右侧不是列表被判定为类型错误而拒绝,此行为合理。 let x = 5在左侧无生成器的情况下被编译器接受,该行为是否符合预期?y <- ...被接受但触发“Defined but not used:”警告,此行为合理。comp5的值为[Right 5,Right 5],此结果是否符合预期?- 原因是
y <- ...从含两个元素的列表生成值,即便y未被使用,仍充当“多重生成器”,即便其左侧无其他生成器。
我测试这类异常/退化的列表推导式时,发现其行为与do块或模式守卫相悖:do块遵循从左到右(从上到下)的作用域规则,末尾需return;模式守卫从左到右作用于<pattern> | <guards> -> <result>,两者均仅按代码序列执行一次。
该如何在脑中建模列表推导式的行为,避免困惑?
补充:(看到@leftroundabout的回答后)
仅对未使用的生成器绑定变量y给出警告(需开启-W才能看到)似乎不合理,我认为GHC应对此类情况给出更强烈的提示。
内容的提问来源于Stack Exchange,提问作者AntC
相关产品推荐
相关产品推荐

