简体   繁体   English

我可以在Haskell上使用let in guard吗?

[英]Can I use let in guards on Haskell?

right now I have an error that says parse error on input '|' 现在我有一个错误,说输入'|'上的解析错误 that refers to the '|' 指的是'|' before the if statement. 在if语句之前。 I am also not sure if I can use let in guards like the code below. 我也不确定我是否可以像下面的代码那样使用let in guard。 The code below is an example to my problem, please help to correct my mistakes, thank you in advance! 下面的代码是我的问题的一个例子,请帮助纠正我的错误,提前谢谢!

func x y
   | let 
       sum = x + y
       mult = x * y
   | if sum == 3
       then do
            sum+=1
       else if mult == 5
           then do
                mult -=1

In fact, Haskell2010 allows the let expression to appear in the guard. 实际上,Haskell2010允许let表达式出现在后卫中。 See the report here . 请在此处查看报告。 |let decls introduces the names defined in decls to the environment. |let declsdecls定义的名称引入环境。

For your case, we can write 对于你的情况,我们可以写

fun x y 
  | let sum = x + y, sum == 3 = Just (sum + 1)
  | let mult = x * y, mult == 5 = Just (mult - 1)
  | otherwise = Nothing

Unfortunately, we can not do that with let . 不幸的是,我们不能做到这一点与let

More precisely, we can write 更确切地说,我们可以写

func x y | let z = .. in condition = result
         | otherCondition          = otherResult

but z will only be visible in condition , and not in result , otherCondition or otherResult . z将只在可见的condition ,而不是resultotherConditionotherResult

(This can be improved using pattern guards, but not completely: z will still be unavailable in otherCondition and otherResult ) (这可以通过使用模式警卫得到改善,但不完全: z仍然不可用在otherConditionotherResult

The solution is using where instead: 解决方案是where使用:

  func x y | condition      = result
           | otherCondition = otherResult
           where z = ...

Here, z is visible everywhere. 在这里, z随处可见。

(Personally, I dislike this form of where because it is too far from the uses of z , but I can't see any simple alternative in this case.) (就个人而言,我不喜欢这种形式where因为它离z的使用太远了,但在这种情况下我看不到任何简单的替代方案。)

Finally, let me add that your code does not look functional to me: there's no if then without else in functional programming, and mult -= 1 can not modify variable mult (the same holds for sum += 1 ). 最后,让我补充一点,你的代码对我来说看起来不起作用: if then没有函数编程中的else if then没有了,而mult -= 1不能修改变量mult (对于sum += 1 )。

You can use let in the top however it has to be followed by an in to designate the block where the defined values are to be used. 您可以在顶部使用let ,但必须后跟in以指定要使用定义值的块。 Also you are missing the condition about what to do if sum /= 3 and mul /= 5 . 如果sum /= 3mul /= 5你也错过了该做什么的条件。 So may be returning a Maybe type could be better such as 所以可能会返回一个Maybe类型可能会更好,例如

func :: Integral a => a -> a -> Maybe a
func x y = let sum = x + y
               mul = x * y
            in case (sum, mul) of
               (3, _) -> Just (sum + 1)
               (_, 5) -> Just (mul - 1)
               _      -> Nothing

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM