2

因此,我搜索了在 Haskell 中处理“if”语句的不同方法,并对守卫有疑问,比如我有一个元组并想要执行 +,-,*,/ 检查条件:

给定 (x,y) if x < y only +,* 因为我只想要整数,此外检查除法以便 x mody == 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:单个函数中的多个 case 语句

但失败,否则是如果 x == y

4

2 回答 2

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)]
于 2013-04-05T17:54:52.817 回答
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

于 2013-04-07T02:21:51.100 回答