burrito burrito
burrito burrito

Reputation: 3

Haskell - Parameter count that fit criteria?

Let's say I have a function:

isOne :: Int -> Int -> Int
isOne x y =

Then if x == 1 and y != 1 then it returns 1 (one of the parameters equals 1), if x == 1 and y == 1 it returns 2 (because both are 1), if x != 1 and y != 1 it returns 0 etc.

I can't figure out how to do more than a single check with an if statement (or using cases).

Upvotes: 0

Views: 168

Answers (4)

leftaroundabout
leftaroundabout

Reputation: 120711

I'd second using either direct pattern matching in the function definition, or case on tuples.

But the most readable alternative would IMO be length [ q | q<-[x,y], q==1 ].

Upvotes: 3

Philip JF
Philip JF

Reputation: 28539

The easiest way to this is with pattern matches. You can define a function by cases, which are interpreted in the order at which they occur

isOne 1 1 = 2
isOne 1 _ = 1
isOne _ 1 = 1
isOne _ _ = 0

alternatively, you can use guards

isOne x y | (x == 1) && (y == 1) = 2
          | (x == 1) && (y != 1) = 1
          | (x != 1) && (y == 1) = 1
          | otherwise            = 0

again, these are checked from top to bottom. That is, if the first guard matches then it goes with the first equation, otherwise it tries the second, and so on. This can also be written

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

or

isOne x y | (x == 1) && (y == 1) = 2
isOne x y | (x == 1) || (y == 1) = 1
isOne x y | otherwise            = 0

another way of doing it would be to use an if then else expression.

isOne x y = if (x == 1) && (y == 1) 
            then 2 
            else if (x == 1) || (y == 1) then 1 else 0

or perhaps you could try doing

isOne x y = (go x) + (go y) where
   go 1 = 1
   go _ = 0

or any of dozens of other ways...

Upvotes: 5

J. Abrahamson
J. Abrahamson

Reputation: 74354

Method 1

Use paired case statements

isOne x y = case (x, y) of 
  (1, 1) -> 2
  (1, _) -> 1
  (0, 0) -> 0
  ...

Method 2

Use nested if statements

isOne x y = if x == 1 then (if y == 1 then 2 else 1) else 0

Upvotes: 4

Ingo
Ingo

Reputation: 36339

Why, you just need to translate your english to Haskell:

if (x==1) && (y /= 1) then 1
else if (x/=1) && (y==1) then 1
...

But you really want:

isOne 1 1 = 2
isOne 1 _ = 1
isOne _ 1 = 1
isOne _ _ = 0

or, even shorter:

isOne x y = fromEnum (x==1) + fromEnum (y==1)

Upvotes: 6

Related Questions