Haskell中的警卫,使用检查执行操作

时间:2013-04-05 17:49:32

标签: haskell tuples

所以我已经搜索了接近Haskell中“if”语句的不同方法,并对守卫产生了疑问,说我有一个元组并想要执行+, - ,*,/检查条件:

给定(x,y)如果x < y只有+,*因为我只想要整数,所以检查除法,以便x mod y == 0或不,这编译但我不能让它运行

operaciones (x,y) = (x,y)
x,y | x < y = [(x, y, '+', x+y), (x, y, '*', x*y)]
    | (x > y) && (x `mod ` y == 0) = [(x, y, '+', x+y), (x, y, '*', x*y), (x, y, '-', x-y) , (x, y, '/', x/y)]
    | (x > y) && (x `mod ` y /= 0) = [(x, y, '+', x+y), (x, y, '*', x*y), (x, y, '-', x-y)]
    | otherwise  = [(x, y, '+', x+y), (x, y, '*', x*y), (x, y, '-', x-y) , (x, y, '/', x/y)]

我接受了

的想法
  

Haskell: Multiple Case Statements in Single Function

但失败了,否则就是x == y

2 个答案:

答案 0 :(得分:7)

你所写的不是合法的语法。

你可能想要这个:

operaciones (x,y)
    | x < y = [(x, y, '+', x+y), (x, y, '*', x*y)]
    | (x > y) && (x `mod ` y == 0) = [(x, y, '+', x+y), (x, y, '*', x*y), (x, y, '-', x-y) , (x, y, '/', x/y)]
    | (x > y) && (x `mod ` y /= 0) = [(x, y, '+', x+y), (x, y, '*', x*y), (x, y, '-', x-y)]
    | otherwise  = [(x, y, '+', x+y), (x, y, '*', x*y), (x, y, '-', x-y) , (x, y, '/', x/y)]

答案 1 :(得分:3)

我不推荐这种风格;你是在重复自己。据我了解,你想要这个功能:

operaciones (x, y) = [
    (x, y, '+', x + y),
    (x, y, '*', x * y),
    (x, y, '-', x - y),
    (x, y, '/', x / y) ]

结果列表已过滤为仅包含正整数结果。 (顺便说一下,至少在英语中,惯例是'整数'包括负数和0,所以你包括差异的条件比'整数结果'更严格。)

我会通过连接列表推导来进行过滤:

operaciones (x, y) =
    [ (x, y, '+', x + y) ] ++
    [ (x, y, '*', x + y) ] ++
    [ (x, y, '-', x + y) | x > y ] ++
    [ (x, y, '/', x `div` y) | x >= y, x `mod` y == 0 ] -- I'm assuming x and y have type Int or Integer, so you should use div not /

另一个注意事项:在Haskell中通常不会将多个参数组合成一个像(x,y)这样的元组;因此,如果xy是单独的参数,那么您的函数头应该写成

operaciones x y =

代替。 (编译器的编写方式,优化器实际上还需要做额外的工作来将(x, y)的元组组合到单独的表单中,所以最好将它保存到工作中。)

更新:我不能认为这是一种干净的错误报告方式。我可能最终会采用混合风格,使用警卫进行错误检查和连接成功案例:

operaciones x y
    | x <= 0 || y <= 0 = Left "Use positive numbers"
    | otherwise = Right $
        [ (x, y, '+', x + y) ] ++ -- etc. as above

如果您真的想要,可以使用error代替Left并省略Right