Answering this question, I realized that Haskell
allows you to deconstruct object when declaring function and use it to do parallel function definitions.
Basically, let's imagine I would like to do something like this
a = (1+)
b = (2+)
c = (3+)
d = (4+)
e = (5+)
What would be the DRYest way to write it ? I mean, after all the pattern is the same: The name of function can't be guessed neither the amount to add, but I should be able to avoid to write +
every time (without using Template Haskell of course).
Basically, I would like to be able to use map
or something similar and It appears that map
just works!.
[a,b,c,d,e] = map (+) [1..5]
Et voila !
That's much shorter and maybe more expressive, and it works :
> a 10
11
> b 10
12
etc ...
So my question is , is it a good pattern to use (in that kind of situation) and if not, which are the draw backs (I know buy experience that the equivalent in Ruby is a nightmare, but the reasons doesn't seems to apply with Haskell)?
I understand the readability of such code is subjective and can be seen as opinion-based. However, there might be some objective reasons to not do it. For example, in Ruby (1.8 at least), methods defined using define_method
are invisible to most IDEs and tags builder. Moreover, you can't step into them using the debugger etc... which make them really unconvenient in practice. I'm asking for similar reason in Haskell
One downside with
[a,b,c,d,e] = map (+) [1..5]
is that it requires non-exhaustive pattern-matching - the match isn't statically guaranteed to be valid. Obviously in this case there's no problem, but in a more subtle example where perhaps [1..5]
was defined elsewhere, it might be harder to see.
I also don't see any particular advantage to this style in this particular case, though I realise it is a bit of a contrived example.
One case where defining multiple values in a single line is worthwhile is if you have a function that returns a tuple, e.g:
(xs, ys) = unzip [(1, 'a'), (2, 'b')]
This can be accomplished using the package for homogeneous tuples (which I'm the author of):
import Data.Tuple.Homogenous
...
let Tuple4 (a, b, c, d) = fmap (+) $ Tuple4 (1, 2, 3, 4)
in ...
without resorting to non-exhaustive pattern matching.
Also there is another similar package tup-functor.
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