2016-08-26 12 views
3

Я пытаюсь определить примитивную рекурсию в терминах foldr, как объясняется в A tutorial on the universality and expressiveness on fold глава 4.1.Строгость сопоставления шаблонов против деконструирования

Вот первая попытка у него

simpleRecursive f v xs = fst $ foldr g (v,[]) xs 
    where 
    g x (acc, xs) = (f x xs acc,x:xs) 

Однако приведенное выше определение не останавливается на head $ simpleRecursive (\x xs acc -> x:xs) [] [1..]

Ниже определение, что остановить

simpleRecursive f v xs = fst $ foldr g (v,[]) xs 
    where 
    g x r = let (acc,xs) = r 
      in (f x xs acc,x:xs) 

Учитывая почти аналогичное определение, но другой результат, почему он отличается? Это связано с тем, как шаблон Haskell соответствует?

+1

Вероятно, связано с вопросом обзорного с 'xs', так как перемещение его в определении' G' исправляет эту проблему. – chepner

ответ

3

Решающее различие между этими двумя функциями является то, что в

g x r = let (acc, xs) = r 
     in (f x xs acc, x:xs) 

матч узор на конструктор кортежа неопровержимо, тогда как в

g x (acc, xs) = (f x xs acc, x:xs) 

это не так. Другими словами, первое определение g эквивалентно

g x ~(acc, xs) = (f x xs acc, x:xs) 
+0

Вы имеете в виду, что проблема в некотором r, которая не соответствует (acc, xs)? –

+0

не означает (v, []), что r всегда в форме (acc, xs)? –

+0

Нет, поскольку последующие рекурсивные вызовы функции не передаются '(v, [])', но все, что возвращается 'g'. – Cactus

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

  • Нет связанных вопросов^_^