26

What does

irrefutable pattern failed for pattern

mean? What cases will cause this runtime error?

Will Ness
  • 70,110
  • 9
  • 98
  • 181

3 Answers3

28

Consider this example:

foo ~(Just x) = "hello"
main = putStrLn $ foo Nothing

This uses an irrefutable pattern (the ~ part). Irrefutable patterns always "match", so this prints hello.

foo ~(Just x) = x
main = putStrLn $ foo Nothing

Now, the pattern still matched, but when we tried to use x when it wasn't actually there there we got an irrefutable pattern match error:

Irr.hs: /tmp/Irr.hs:2:1-17: Irrefutable pattern failed for pattern (Data.Maybe.Just x)

This is subtly distinct from the error you get when there's no matching pattern:

foo (Just x) = x
main = putStrLn $ foo Nothing

This outputs

Irr.hs: /tmp/Irr.hs:2:1-16: Non-exhaustive patterns in function foo

Of course, this is a somewhat contrived example. The more likely explanation is that it came from a pattern in a let binding, as chrisdb suggested.

Community
  • 1
  • 1
hammar
  • 138,522
  • 17
  • 304
  • 385
  • 1
    I think that might be mistaken `~xyz` (IMO it's called *lazy pattern*) is one example of an irrefutable pattern but not the only one - I just remark because I saw people calling `~` **the** irrefutable pattern – Random Dev Jul 13 '17 at 09:58
20

Well, I assume it means what it says - that a pattern doesn't match but there is no alternative. This example:

But for the program:

g x = let Just y = f x in h y 

GHC reports:

Main: M1.hs:9:11-22:
    Irrefutable pattern failed for pattern Data.Maybe.Just y 

Indicating the source of the failure.

Comes from http://www.haskell.org/haskellwiki/Debugging

The point of the example is that if f x returns Nothing then there is no way GHC can assign a value to y.

Cactus
  • 27,075
  • 9
  • 69
  • 149
chrisdb
  • 1,115
  • 6
  • 12
9

To add what others have said, you could technically get it if you're disconnecting a list that's smaller than what you're intending. For example (in GHCi):

Prelude> let l = [1,2,3]
Prelude> let (x:x1:xs) = l
Prelude> x
1

Works fine, but if you did:

Prelude> let l2 = [1]
Prelude> let (x:x1:xs) = l2
Prelude> x
*** Exception: <interactive>:294:5-18: Irrefutable pattern failed for pattern (x : x1 : xs)
antimatter
  • 3,240
  • 2
  • 23
  • 34