2016-12-25 3 views
3

В parallel list comprehension в Haskell я столкнулся с проблемой при попытке использовать охрану.Использование переменных в параллельных списках в Haskell

largestPalindrome :: Int -> Int 
largestPalindrome x = maximum [ a*b 
           | a <- [x,x-1..1] 
           | b <- [x,x-1..1] 
           , isPalindrome (a*b) ] 

Ошибка, которая отображается в

Variable not in scope: a :: Int 
+0

Если вы сделаете это параллельно, вы не сможете связать 'a' и' b', я прав? Что ты пытаешься сделать? – Euge

+0

Обратите внимание: если вы их вычисляете параллельно, вы всегда получаете 'b = a'. – chi

ответ

5

Цитируется Haskell Prime:

Параллельные постижения расширить списковые с обозначениями для молний. Понимание

[ e | quals1 | ... | qualsN ] 

может быть обессахаренная к

zipWithN (\ p1 ... pN -> e) [p1 | quals1] ... [pN | qualsN] 

где pi является кортеж переменных, определенных qualsi и используемых e.

Таким образом, из вашего примера, [a*b |a<- [x,x-1..1] | b <- [x,x-1..1] , isPalindrome (a*b)] примерно эквивалентно

zipWith (\a b -> a*b) 
     [ a | a<-[x,x-1..1] ] 
     [ b | b <- [x,x-1..1], isPalindrome (a*b) ] 

где достаточно понятно, почему a не в области видимости последнего списка понимания. Интуитивно, вы должны думать о том, что каждая ограниченная часть | является полностью независимой от других. Любая операция фильтрации будет связана только с одной из этих частей.

+0

Не просто заменил бы второй '' '' '', трюк? – Arnon

+1

@Arnon Нет, тогда это будет обычное понимание списка, а не параллельное, что не будет 'zipWith', а скорее' concatMap'. –

+0

Это, по крайней мере, объяснение. Я сам посмотрел на это определение, но, поскольку я очень новичок в Haskell (Started Yesterday), я не совсем понял его. Любые советы о том, как на самом деле исправить это? – Zulraidur

Смежные вопросы