Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closures and list comprehensions in Haskell

I'm playing around with Haskell at the moment and thus stumbled upon the list comprehension feature. Naturally, I would have used a closure to do this kind of thing:

Prelude> [x|x<-[1..7],x>4] -- list comprehension
[5,6,7]
Prelude> filter (\x->x>4) [1..7] -- closure
[5,6,7]

I still don't feel this language, so which way would a Haskell programmer go? What are the differences between these two solutions?

like image 693
Zakum Avatar asked Oct 04 '11 17:10

Zakum


People also ask

What are list comprehensions in Haskell?

List comprehension in Haskell is a way to produce the list of new elements from the generator we have passed inside it. Also for the generator values, we can apply the Haskell functions to modify it later. This list comprehension is very y easy to use and handle for developers and beginners as well.

What is the difference between list comprehension and lambda?

The difference between Lambda and List Comprehension. List Comprehension is used to create lists, Lambda is function that can process like other functions and thus return values or lists.

How do I display lists in Haskell?

Example #1print("Demo to show list in Haskell !!") let list1 = [100, 50, 235, 167, 345, 909, 675, 20] let list2 = [1, 2, 3, 4, 5, 6, 7, 8, 9] let list3 = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6] let list4 = [5, 10, 15, 20, 15, 30, 35, 40] let list5 = [123.4, 567.9, 56.0, 3.9, 76.9] print("printing list element !!")


2 Answers

Idiomatic Haskell would be filter (> 4) [1..7]

Note that you are not capturing any of the lexical scope in your closure, and are instead making use of a sectioned operator. That is to say, you want a partial application of >, which operator sections give you immediately. List comprehensions are sometimes attractive, but the usual perception is that they do not scale as nicely as the usual suite of higher order functions ("scale" with respect to more complex compositions). That kind of stylistic decision is, of course, largely subjective, so YMMV.

like image 157
Anthony Avatar answered Sep 28 '22 09:09

Anthony


List comprehensions come in handy if the elements are somewhat complex and one needs to filter them by pattern matching, or the mapping part feels too complex for a lambda abstraction, which should be short (or so I feel), or if one has to deal with nested lists. In the latter case, a list comprehension is often more readable than the alternatives (to me, anyway).

For example something like:

[ (f b, (g . fst) a) | (Just a, Right bs) <- somelist, a `notElem` bs, (_, b) <- bs ]

But for your example, the section (>4) is a really nice way to write (\a -> a > 4) and because you use it only for filtering, most people would prefer ANthonys solution.

like image 38
Ingo Avatar answered Sep 28 '22 09:09

Ingo