Haskell style list comprehensions in Ruby
gist.github.com
gist.github.com
require 'multiarray'
include Hornetseye
# Object
lazy(4) { |i| i + 2 }
# Sequence(INT):
# [ 2, 3, 4, 5 ]
lazy(3, 2) { |x, y| x }
# MultiArray(INT,2):
# [ [ 0, 1, 2 ],
# [ 0, 1, 2 ] ]
lazy(3, 2) { |x, y| x + 1 }
# MultiArray(INT,2):
# [ [ 1, 2, 3 ],
# [ 1, 2, 3 ] ]
lazy(3, 3) { |x, y| y + 4 }
# MultiArray(INT,2):
# [ [ 4, 4, 4 ],
# [ 5, 5, 5 ],
# [ 6, 6, 6 ] ]
lazy(3, 3) { |x, y| (x + 1) * (y + 4) }
# MultiArray(INT,2):
# [ [ 4, 8, 12 ],
# [ 5, 10, 15 ],
# [ 6, 12, 18 ] ]
lazy { |x,y| Sequence['n', 'p', 'r', 't'][x] + Sequence['a', 'i', 'u', 'e', 'o'][y] }
# MultiArray(OBJECT,2):
# [ [ "na", "pa", "ra", "ta" ],
# [ "ni", "pi", "ri", "ti" ],
# [ "nu", "pu", "ru", "tu" ],
# [ "ne", "pe", "re", "te" ],
# [ "no", "po", "ro", "to" ] ]
s = lazy(33) { |i| 3 * (i+1) }
# Sequence(INT):
# [ 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, .... ]
s.mask((s % 2).eq(0)).collect { |i| i ** 2 / 3 }
# Sequence(INT):
# [ 12, 48, 108, 192, 300, 432, 588, 768, 972, 1200, 1452, 1728, .... ]
[1] https://github.com/wedesoft/multiarray
[2] http://www.wedesoft.de/hornetseye-api/And with -XMonadComprehensions you can have the compiler do that for a whole bunch more Monads.
Still very nice though.
What do you find ugly about them?
EDIT: On a more elaborate note, I think that the extreme variety of programming styles enabled by Haskell is more of a weakness than a strength. True, defining your own abstractions and operators is part of the fun, but seeing declarative style (pattern-matching in function defs, where blocks, function args on left-hand side, guards), expression style (let blocks, lambda abstractions, case statements, if clauses), applicative style (<$>, <* >, <$, <* , * >, <|>), and arrow style (* * * , &&&, ^>>, ^<<, >>^, <<^, <+>, +++, |||, >>>, <<<) all in the same file can get pretty overwhelming even if you're already pretty fluent in the language.
We don't need any help being confusing, people. We already have Monads, for god's sake.
http://hackage.haskell.org/trac/ghc/wiki/MonadComprehensions
Edit: didn't realise you were the author :)
It's one of those hacks that are cute and great to play with and awesome proof of concept for new features, but if I saw it in a production codebase, I'd want to strangle someone.
EDIT: just realized you're the author, so your comment must be out of modesty. Anyway, it deserves, and kudos to you ;)
The unary operators `def -@` gets called when you do something like: `-[1,2,3]`.
So in the example code at the bottom, it's doing `bar =+ [x | x <- [1..3]]` that's better parsed as `bar = +[x | x <- [1..3]]` (note the spacing difference).
Hacking unary operators has a long history in silliness in ruby. See also: https://github.com/jicksta/superators
I am the only one?
Dict comprehensions are just a little muddier, even for simple things, but a single line of debug output after the comprehension should confirm whether or not you're getting the structure you expect, provided you are still doing only trivial work inside your comprehension.
[0] - http://google-styleguide.googlecode.com/svn/trunk/pyguide.ht...