Ошибка разбора лямбда-выражения на ")"

Моя задача состоит в том, чтобы повторно реализовать эту функцию

divn :: Integer -> [Integer] -> [Integer]
divn _ [] = []
divn n (x:xs) | mod x n == 0 = x : divn n xs
              | otherwise = divn n xs

используя 'foldr'. Что я сделал:

divn' _ [] = []
divn' n (x:xs) = foldr (\x -> if (mod x n == 0) (x:) ([]++)) [] xs

Я думал, что это будет работать. На самом деле он даже не компилируется, но говорит: "Ошибка разбора при вводе")".

Так как я не нашел никаких ошибок, я решил переписать, как будто теперь это работает...

if' True x _ = x
if' False _ x = x

divn' _ [] = []
divn' n (x:xs) = foldr (\x -> if' (mod x n == 0) (x:) ([]++)) [] xs

Кто-нибудь знает где ошибка?

Спасибо!

2 ответа

Решение

if нужен then и else в Хаскеле,

(\x -> if (mod x n == 0) (x:) ([]++))

должно быть

(\x -> if (mod x n == 0) then (x:) else id)

Помимо того, что сказал Дэниел Фишер, вам не нужны никакие отдельные случаи: рекурсии нет, случай с пустым списком будет обрабатываться Foldr. В вашем коде первый x всегда игнорируется! Правильный

divn' n xs = foldr (\x -> if x`mod`n == 0 then (x:) else id) [] xs

или, путем η-восстановления,

divn' n = foldr (\x -> if x`mod`n == 0 then (x:) else id) []

Конечно, было бы гораздо более идиоматичным просто

divn'' n = filter ((==0) . (`mod`n))
Другие вопросы по тегам