'Express a "case ... of" pattern more elegantly in Haskell

I came across a pattern which I believe can be expressed more elegantly:

I have two functions f1,f2 :: Int -> Int (their impl. is not relevant), and a process :: Int -> Int which does the following:

  • if f1 x produces x1 different from x, then repeat the process with x1
  • otherwise, if f2 x produces x2 different from x, then repeat the process with x2
  • finally, stop the process and return x

My case ... of implementation is the following:

f1 :: Int -> Int
f1 = undefined

f2 :: Int -> Int
f2 = undefined

process :: Int -> Int
process x =
    case f1 x of
        x ->
            case f2 x of
                x -> x
                x' -> process x'
        x' -> process x'

which produces the following warnings:

so.hs:13:17: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: x' -> ...
   |
13 |                 x' -> process x'
   |                 ^^^^^^^^^^^^^^^^

so.hs:14:9: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: x' -> ...
   |
14 |         x' -> process x'
   |         ^^^^^^^^^^^^^^^^

Can anyone shed some light as to what patterns are overlapping, and how to implement process more elegantly?



Solution 1:[1]

Following Ben's advice, I wrote the following:

process :: Int -> Int
process x
    | x /= x1 = process x1
    | x /= x2 = process x2
    | otherwise = x
  where
    x1 = f1 x
    x2 = f2 x

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alexandru Dinu