Эта функция может работать с бесконечными списками ассоциаций, и легко понять, почему:
findKey :: (Eq k) => k -> [(k,v)] -> Maybe v
findKey key [] = Nothing
findKey key ((k,v):xs) = if key == k
then Just v
else findKey key xs
Когда он находит ключ, он возвращает Just v
, останавливая рекурсию. Теперь посмотрите на эту другую реализацию:
findKey' :: (Eq k) => k -> [(k,v)] -> Maybe v
findKey' key = foldr (\(k,v) acc -> if key == k then Just v else acc) Nothing
Откуда компилятор/интерпретатор знает, что когда ключ соответствует k, он может его вернуть?
*Main> findKey' 1 $ zip [1..] [1..]
возвращает Just 1
Когда он находит это key == k
, он возвращает Just v
. Почему на этом рекурсия останавливается, позволяя нам делать такие вещи с бесконечными списками ассоциаций?
acc
не является аккумулятором (слева); это рекурсивный результат (справа), поэтому лучше называть егоr
, чтобы избежать когнитивного диссонанса. - person Will Ness   schedule 07.06.2015