Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is parallel declaration of function a good idea?

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)?

Update

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

like image 321
mb14 Avatar asked Jul 06 '14 12:07

mb14


2 Answers

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')]
like image 107
GS - Apologise to Monica Avatar answered Nov 07 '22 06:11

GS - Apologise to Monica


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.

like image 6
Petr Avatar answered Nov 07 '22 07:11

Petr