Как foldr работает?

Я не использовал Эмулятор Android, но я установил переменную среды $http_proxy для жемчуга и wget и нескольких cygwin инструментов на окнах. Это могло бы работать на Вас для андроида, но наклонная черта в доменном имени походит на потенциальную проблему. Я знаю, что попытался иметь свой домен "GLOBAL" там, но закончил тем, что вынул его и придерживался с: http://$USER:password@www-proxy.company.com:80

Одна проблема я сталкиваюсь со много, хотя программы, которым нельзя сказать использовать прокси для запросов DNS также. В случаях, где они не, я всегда получаю имя хоста, не найденное. Я хотел бы найти локальный dns преобразователь, который может использовать прокси для всех программ, которые не будут.

62
задан nbro 9 April 2017 в 14:22
поделиться

6 ответов

foldr начинается с правого конца списка и объединяет каждую запись списка со значением аккумулятора, используя заданную вами функцию. Результатом является окончательное значение аккумулятора после «сворачивания» всех элементов списка. Его тип:

foldr :: (a -> b -> b) -> b -> [a] -> b

, и отсюда вы можете видеть, что элемент списка (типа a ) является первым аргументом данной функции, а аккумулятор (типа b ) является вторым.

Для вашего первого примера:

Starting accumulator = 54
11 -   54  = -43
10 - (-43) =  53

        ^  Result from the previous line

 ^ Next list item

Итак, вы получили ответ 53.

Второй пример:

Starting accumulator = 54
(6  + 54) / 2 = 30
(10 + 30) / 2 = 20
(4  + 20) / 2 = 12
(12 + 12) / 2 = 12

Итак, результат 12.

Edit: Я хотел добавить, это для конечных списков. foldr также может работать с бесконечными списками, но я думаю, что лучше сначала разобраться с конечным случаем.

78
ответ дан 24 November 2019 в 16:29
поделиться

Простой способ понять foldr заключается в следующем: он заменяет каждый конструктор списка приложением предоставленной функции. Ваш первый пример будет переведен на:

10 - (11 - 54)

из:

10: (11: [])

Хороший совет, который я получил от Haskell Wikibook, может быть здесь могут быть полезны:

Как правило, вы должны использовать foldr для списков, которые могут быть бесконечными или в которых свертка формирует структуру данных, и foldl ', если список как известно, конечен и сводится к единственному значению. foldl (без галочки) вообще не следует использовать.

6
ответ дан 24 November 2019 в 16:29
поделиться

Подумайте о foldr очень определении :

 -- if the list is empty, the result is the initial value z
 foldr f z []     = z                  
 -- if not, apply f to the first element and the result of folding the rest 
 foldr f z (x:xs) = f x (foldr f z xs)

Например, foldr (-) 54 [10,11] должен равняться (-) 10 (foldr (-) 54 [11]) , т.е. снова расширяться, равняться (-) 10 ((-) 11 54) . Таким образом, внутренняя операция 11 - 54 , то есть -43; а внешняя операция - 10 - (-43) , то есть 10 + 43 , следовательно, 53 , как вы заметили. Выполните аналогичные шаги для второго случая, и вы снова увидите, как формируется результат!

21
ответ дан 24 November 2019 в 16:29
поделиться

foldr означает складывание справа, поэтому foldr (-) 0 [1, 2, 3] дает (1 - (2 - ( 3-0))) . Для сравнения foldl дает (((0 - 1) - 2) - 3) .

Когда операторы не коммутативны, foldl и foldr даст разные результаты.

В вашем случае первый пример расширяется до (10 - (11 - 54)) , что дает 53.

14
ответ дан 24 November 2019 в 16:29
поделиться

Я всегда считал http://foldr.com забавной иллюстрацией. См. Сообщение Lambda the Ultimate .

5
ответ дан 24 November 2019 в 16:29
поделиться

Самый простой способ понять foldr - это переписать список, который вы сворачиваете, без сахара.

[1,2,3,4,5] => 1:(2:(3:(4:(5:[]))))

Теперь то, что делает foldr fx , это то, что он заменяет каждый : с f в инфиксной форме и [] с x и оценивает результат.

Например:

sum [1,2,3] = foldr (+) 0 [1,2,3]

[1,2,3] === 1:(2:(3:[]))

so

sum [1,2,3] === 1+(2+(3+0)) = 6
121
ответ дан 24 November 2019 в 16:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: