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.
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.".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With