Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching for return values

I know I can use pattern matching for function parameters like this:

fn :: (Integral a) => (a,a) -> (a, a)
fn (x,y) = (y,x)

But how can I match the return value? I would expect something like this:

g :: (Integral a) => a -> a
g z = do
  (x, y) = fn (z, z + 5)
  x `mod` y

This results in a syntax error. Is there a way to match return values? Basically, I want to split the returned tuple into two variables.

like image 822
just.me Avatar asked Mar 02 '26 20:03

just.me


1 Answers

The do is used a syntactical sugar for monads. Your function is however not a monad.

What you can do is use a let-clause, like:

g :: (Integral a) => a -> a
g z = let (x,y) = fn (z,(z+5)) in x `mod` y

Or a where-clause:

g :: (Integral a) => a -> a
g z = x `mod` y
    where (x,y) = fn (z,(z+5))

You can also define a pattern in a lambda-expression, like:

g :: (Integral a) => a -> a
g z = (\(x,y) -> x `mod` y) $ fn (z,(z+5))

Along these lines, you can also define a helper function that does the pattern matching, like:

g :: (Integral a) => a -> a
g z = h $ fn (z,(z+5))
    where h (x,y) = x `mod` y

This can be useful if there are several patterns that need to be handled differently (like the Nothing and Just x for the Maybe a type).

Say for instance that you defined a function:

foo :: Int -> Int -> Maybe Int
foo x y | x > y = Just x
        | otherwise = Nothing

than you can define bar with a helper function qux to handle the output of foo, like:

bar :: Int -> Int -> Int
bar x y = qux $ foo x y
    where qux Nothing = y
          qux (Just z) = z

Finally in the case of 2-tuples, you can decide not to use pattern matching, but use fst :: (a,b) -> a and snd :: (a,b) -> b, like for instance:

g :: (Integral a) => a -> a
g z = let t = fn (z,(z+5)) in ( fst  t) `mod` (snd t)

But this is less elegant since here one has to start thinking about what fst and snd do, and furtermore if not optimized, it can result in additional computation overhead.

Which one to pick depends of course on the context and a bit on personal taste. Since here the pattern is the only one, I would pick the let or where pattern, but like the French say: "Les goûts et les couleurs ne se discutent pas.".

like image 199
Willem Van Onsem Avatar answered Mar 05 '26 21:03

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!