Есть ли способ использовать 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
Но это не 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'
Так что 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
Это кажется немного глупым и немного неясным, хотя и не слишком неэффективным.Тем не менее, было бы неплохо, если бы let
или where
работали во всем понимании.Можно ли это сделать?