¿Hay alguna manera de usar let
, where
o definir de otra manera las subexpresiones en una lista de comprensión para que pueda usarse tanto en el término como en la restricción?haskell - let/where equivalente dentro de la lista de comprensión?
Desde mi experimentación, los siguientes trabajos:
[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
Pero estos no hacen BC de alcance:
[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'
Así let
obras en un lugar u otro, pero no ambos a la vez!
La única forma que he encontrado para hacerlo funcionar (es decir, evitar las repetidas expresiones y posiblemente evaluaciones) es añadir un conjunto unitario lista tonta como lo hice en el siguiente problema (Euler project 38) con x<-[e38cat i [1..k]
como constraitnt a la comprensión de lista:
> let e38cat x l = foldl1 (++) $ map show [x*i | i<-l]
maximum [x| i<-[1..9999], k<-[2..div 10 $ length $ show i], x<-[e38cat i [1..k]], sort x == "123456789"]
"932718654"
O contunuing el ejemplo trivial anterior,
[x | i<-[0..10], x<-[i*i], x > 20] --works
Esto parece un poco tonto, y se le faltaba algo de claridad, aunque no parece demasiado ineficiente. Aún así, sería bueno si let
o where
funcionaran en toda la comprensión. Se puede hacer esto?
Su segundo ejemplo, '[x | i <- [1..10], deje x = i * i en x> 20] ', no compila; ¿quisiste decir '[i * i | i <- [1..10], deje x = i * i en x> 20] '? –
sí, gracias. si el primero funcionó, habría respondido mi propia pregunta –