haskell - эквивалент let / where в понимании списка?

Есть ли способ использовать let , where или иным образом определять подвыражения в понимании списка, чтобы что его можно использовать как в термине, так и в ограничении?

По результатам моих экспериментов, следующая работа:

[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

Но они не входят в область видимости:

[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'

Итак let работает в одном месте или другой, но не оба вместе!

Я нашел единственный способ заставить его работать (то есть избегать повторных выражений и, возможно, вычислений) - это добавить глупый одноэлементный список, как я сделал здесь с x <- [cat i [1..k] в качестве ограничения для понимания списка:

> 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"

Или , продолжая тривиальный пример выше,

[x | i<-[0..10], x<-[i*i], x > 20] --works

Это кажется немного глупым и немного нечетким, хотя и не кажется слишком неэффективным. Тем не менее, было бы неплохо, если бы позволили или , где работали во всем понимании. Можно ли это сделать?

14
задан jon_darkstar 23 March 2018 в 18:26
поделиться