RandomB
RandomB

Reputation: 3737

Strange pattern-matching: is it correct?

Why does this function always succeed? It always returns True with any values and any types. Is this the correct behavior?

f a b = case a of b -> True; _ -> False

Upvotes: 8

Views: 902

Answers (2)

developer_hatch
developer_hatch

Reputation: 16224

Just in addition to the perfect answer accepted, my two cents:

this:

f a b = case a of b -> True; _ -> False -- (A)

and this:

f a b = case a of
                c -> True
                _ -> False --(B)

are is equivalent to:

f a b = case a of
    _ -> True

or

f a b = True

or

f _ b = True

So, be careful because that's the real behavior you created, a function that takes two parameters and returns always True.

Also:

(A) and (B) will show this warning if -Woverlapping-patterns is used:

warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: _ -> ...
  |
3 |               _ -> False
  |               ^^^^^^^^^^

Upvotes: 5

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476594

The b in the case definition is not the b in in the head of the f definition. You created a new locally scoped variable. Your code is thus equivalent to:

f a b = case a of
    c -> True
    _ -> False

Pattern matching with a variable indeed always succeeds.

If you want to check if two values are the same, you will need to define some function (or let Haskell automatically derive Eq for example).

Note: you can turn on the -Wname-shadowing warning to let the compiler warn you about creating identifiers that shadow existing ones. For example your code will produce:

Prelude> f a b = case a of b -> True; _ -> False

<interactive>:1:19: warning: [-Wname-shadowing]
    This binding for ‘b’ shadows the existing binding
      bound at <interactive>:1:5

Upvotes: 24

Related Questions