Home > Back-end >  What is the idiomatic way to share variables between different patterns of the same function?
What is the idiomatic way to share variables between different patterns of the same function?

Time:09-28

I'm starting to get a decent handle on writing code in haskell, and I've noticed a pattern of error that I've committed a few times:

doFoo :: ...
doFoo pattern1 = fooHelper ...
doFoo pattern2 = fooHelper ...
  where
    fooHelper = ...

fooHelper is of course not in scope for doFoo pattern1. I've found myself correcting the error by using a single irrefutable pattern for doFoo and then pattern matching on it using a case expression inside the function:

doFoo :: ...
doFoo irrefutable = case irrefutable of
  pattern1 -> fooHelper ...
  pattern2 -> fooHelper ...
  where
    fooHelper = ...

fooHelper is now of course in scope for both patterns.

As far as I know, pattern matching at the function level is in every way equivalent to pattern matching in case expressions (though please correct me if I'm wrong), so this seems a reasonable thing to do. Would this pattern be considered idiomatic, or is there a better (or just commonly used alternative) way?

CodePudding user response:

I think it's common to convert it into an case expression in this case. In addition to that, with LambdaCase extension, you can make it a little bit shorter.

doFoo :: ...
doFoo = \case
  pattern1 -> fooHelper ...
  pattern2 -> fooHelper ...
  where
    fooHelper = ...

As of GHC 9.4.1, you can even pattern match on multiple parameters. So, for example, you can write something like this:

doFoo :: ...
doFoo = \cases
  pattern1 pattern1' -> fooHelper ...
  pattern2 pattern2' -> fooHelper ...
  where
    fooHelper = ...

instead of writing

doFoo :: ...
doFoo x y = case (x, y) of
  (pattern1, pattern1') -> fooHelper ...
  (pattern2, pattern2') -> fooHelper ...
  where
    fooHelper = ...

Note that it's \cases, not \case

  • Related