Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell - List Comprehension Predicates Optimization

Tags:

haskell

This is an example from Learn you a Haskell:

ghci> [ x*y | x <- [2,5,10], y <- [8,10,11], x*y > 50]  
[55,80,100,110]   

So, what's going on here, will x*y be calculated twice or once?

like image 340
CamelCamelCamel Avatar asked Sep 10 '12 15:09

CamelCamelCamel


3 Answers

It would be calculated twice unless common subexpression elimination occurs.

Depending on inlining and your optimization level, GHC may do quite aggressive things with the list comprehension.

In general, you should explicitly share common expressions to guarantee sharing.

like image 51
Don Stewart Avatar answered Nov 18 '22 06:11

Don Stewart


To be sure of the compiler's behaviour, prefer:

[ product | x <- [2, 5, 10]
          , y <- [8, 10, 11]
          , let product = x * y
          , product > 50] 
like image 26
m09 Avatar answered Nov 18 '22 07:11

m09


Looking into the core when compiled with -O2 option it has following lines (relevant and simplified)

          case (y_aAD * sc_s1Rq) > 50 of 
            False -> go_XB2 sc1_s1Rr;
            True -> (y_aAD * sc_s1Rq):(go_XB2 sc1_s1Rr)

This clearly shows that the multiplication is calculated twice, so it is better use common expression to prevent recomputation.

like image 37
Satvik Avatar answered Nov 18 '22 07:11

Satvik