我们说我有一个功能:
isOne :: Int -> Int -> Int
isOne x y =
然后,如果x == 1
和y != 1
则返回1
(其中一个参数等于1),如果x == 1
和y == 1
则返回{{1} (因为两者都是1),如果2
和x != 1
返回y != 1
等。
我无法弄清楚如何使用if语句(或使用案例)进行多次检查。
答案 0 :(得分:6)
为什么,你只需将你的英语翻译成Haskell:
if (x==1) && (y /= 1) then 1
else if (x/=1) && (y==1) then 1
...
但你真的想要:
isOne 1 1 = 2
isOne 1 _ = 1
isOne _ 1 = 1
isOne _ _ = 0
或者更短:
isOne x y = fromEnum (x==1) + fromEnum (y==1)
答案 1 :(得分:5)
最简单的方法是使用模式匹配。您可以按案例定义函数,按照它们出现的顺序进行解释
isOne 1 1 = 2
isOne 1 _ = 1
isOne _ 1 = 1
isOne _ _ = 0
或者,您可以使用警卫
isOne x y | (x == 1) && (y == 1) = 2
| (x == 1) && (y != 1) = 1
| (x != 1) && (y == 1) = 1
| otherwise = 0
再次,从上到下检查这些。也就是说,如果第一个守卫匹配则它与第一个等式匹配,否则它尝试第二个,依此类推。这也可以写成
isOne x y | (x == 1) && (y == 1) = 2
isOne x y | (x == 1) && (y != 1) = 1
isOne x y | (x != 1) && (y == 1) = 1
isOne x y | otherwise = 0
或
isOne x y | (x == 1) && (y == 1) = 2
isOne x y | (x == 1) || (y == 1) = 1
isOne x y | otherwise = 0
另一种方法是使用if then else
表达式。
isOne x y = if (x == 1) && (y == 1)
then 2
else if (x == 1) || (y == 1) then 1 else 0
或者你可以试试
isOne x y = (go x) + (go y) where
go 1 = 1
go _ = 0
或其他几十种方式......
答案 2 :(得分:4)
使用配对的case
语句
isOne x y = case (x, y) of
(1, 1) -> 2
(1, _) -> 1
(0, 0) -> 0
...
使用嵌套的if
语句
isOne x y = if x == 1 then (if y == 1 then 2 else 1) else 0
答案 3 :(得分:3)
我在函数定义中使用直接模式匹配,或者在元组上使用case
。
但最可读的替代方案是IMO length [ q | q<-[x,y], q==1 ]
。