Is there a way to use let
,where
or otherwise define sub-expressions in a list comprehension so that it can be used both in the term and constraint?
From my experimenting, the following work:
[let x = i*i in x | i<-[1..10], i*i > 20] --good
[i*i | i<-[1..10], let x=i*i in x > 20] --good
But these do not bc of scope:
[let x = i*i in x | i<-[1..10], x > 20] -- 'x' not in scope error
let x = i*i in [x | i<-[1..10], x > 20] -- 'i' not in scope error
[x | i<-[1..10], x > 20] where x = i*i --parse error on 'where'
So let
works in one place or the other, but not both together!
The only way I've found to make it work (that is, avoid repeated expressions and possibly evaluations) is to add a silly singleton-list as I did here with x<-[cat i [1..k]
as a constraint to the list comprehension:
> let cat x l = foldl1 (++) $ map show [x*i | i<-l]
maximum [x| i<-[1..9999], k<-[2..div 10 $ length $ show i], x<-[cat i [1..k]], sort x == "123456789"]
"932718654"
Or, contunuing the trivial example above,
[x | i<-[0..10], x<-[i*i], x > 20] --works
This seems a little silly, and is slightly lacking in clarity, tho it doesn't seem too inefficient. Still, it would be nice if let
or where
worked across the whole comprehension. Can this be done?