Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/22: Рейтинг темы: голосов - 22, средняя оценка - 4.82
 Аватар для a91
4 / 4 / 0
Регистрация: 03.04.2009
Сообщений: 190

Каррирование: что дает, как применять, где использовать?

13.01.2012, 20:24. Показов 4651. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Начал изучать Haskell.

С одной стороны формулировку каррирования я понял.
f : (x,y) -> z эквивалентно f: x->y->z или f: x->(y->z)
т.е в случае каррирования функции, которой передавались два аргумента теперь передается по одному:
функция f принимает значение х, и возвращает другую функцию, которая принимает значение y и возвращает z. Эквивалентная форма записи ничего более.
Промежуточное выражение f х называется частичным применением.
"И частичное применение позволяет фиксировать параметры более общих функций."
Я не понимаю, что значит фиксировать параметры более общих функций, что это дает, как это применять, зачем это используется?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.01.2012, 20:24
Ответы с готовыми решениями:

Matrix4x4 -что это, как пользоваться, где применять?
Здравствуйте! Наткнулся как то давно в чужом проекте на некий Matrix4x4 - тогда вообще не понял что это. Собственно сейчас, спустя...

Что дает IDisposable и как его использовать?
Расскажите пожалуйста если не трудно на пальцах что как и почему? Ибо что то инфы мало нашел в гуглях...

Культура оформления кода: что такое enum? Где, когда и для чего уместно применять этот тип?
не понял за что отвечают эти две строчки: enum ChosenOperation { ADD = 1, SHOW, SEARCH, EXIT }; enum SearchingCriteria { NAME =...

3
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
14.01.2012, 06:57
Лучший ответ Сообщение было отмечено как решение

Решение

Каррирование часто используется в функциях высшего порядка. Например:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- пусть у нас есть более общая функция обработки списков (правая свертка)
-- она принимает комбинирующую фунцию и аккумулирующее значение,
-- и обходит список справа налево, применяя функцию к последовательным
-- элементам списка (с конца) и аккумулирующему значению
list_foldr :: (a -> b -> b) -> b -> [a] -> b
list_foldr _ i []     = i
list_foldr f i (x:xs) = f x (list_foldr f i xs)
 
-- функция подсчета суммы элементов списка
 
-- шаблонное определение (можно заметить, что определение выглядит
-- как частный случай правой свертки)
list_sum_boilerplate :: Num a => [a] -> a
list_sum_boilerplate []     = 0
list_sum_boilerplate (x:xs) = x + list_sum_boilerplate xs
 
-- определение суммы элементов списка через правую свертку
-- здесь мы строим специализированную функцию (list_sum),
-- на основе более общей (list_foldr), фиксируя ее первые два параметра
list_sum :: Num a => [a] -> a
list_sum = list_foldr (+) 0
Еще пример:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
-- нужно построить функцию, которая будет
-- увеличивать каждый элемент списка на 3
 
-- с помощью лямбла-нотации
map_plus_3_ :: Num a => [a] -> [a]
map_plus_3_ = map (\elem -> elem + 3)
 
-- с помощью т.н. "секций" (специальный
-- синтаксис каррирования для инфиксных операторов
-- и двуместных функций, позволяющий зафиксировать
-- любой из двух параметров оператора (функции))
map_plus_3 :: Num a => [a] -> [a]
map_plus_3 = map (+3)           -- фиксируем 2ой пар-р оператора (+)
3
 Аватар для a91
4 / 4 / 0
Регистрация: 03.04.2009
Сообщений: 190
14.01.2012, 16:13  [ТС]
Haskell
1
2
3
4
5
6
-- нужно построить функцию, которая будет
-- увеличивать каждый элемент списка на 3
 
-- с помощью лямбла-нотации
map_plus_3_ :: Num a => [a] -> [a]
map_plus_3_ = map (\elem -> elem + 3)
Почему когда вызываем эту функцию map_plus_3_ без аргументов она вылетает?

Разницу я вижу, а все равно не понимаю почему..
Т.е. нам не нужно писать map elem_p3[list]
можно обойтись map_p3[list] ...

Частичное применение, почему этот термин называется именно так?

Добавлено через 16 минут
Еще вопрос!
Смотрю :type (.)

(b->c)->(a->b)->a->c
почему не, (b->c)->(a->b)->c

Например, есть (square inc ) 3 -- вернет 16
(b->c) это функция square
(a->b) это inc
с это результат 16

Почему функция не отображает применение этих функцию к результату?
Отображение происходит следующим образом (наверняка здесь логическая ошибка): функция (.) принимает аргумент (b->c) и возвращает функцию принимающую аргумент (a->b), которая возвращает функцию принимающую аргумент а и вычисляющую с (результат)



Только с площадь многоугольника никак(

Добавлено через 7 минут
Haskell
1
2
3
4
5
6
-- нужно построить функцию, которая будет
-- увеличивать каждый элемент списка на 3
 
-- с помощью лямбла-нотации
map_plus_3_ :: Num a => [a] -> [a]
map_plus_3_ = map (\elem -> elem + 3)
Я правильн понимаю, что вот этот пример являюется примером на частичное применение?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
14.01.2012, 16:43
Цитата Сообщение от a91 Посмотреть сообщение
Почему когда вызываем эту функцию map_plus_3_ без аргументов она вылетает?
очевидно, что она принимает список, который впоследствии обрабатывает. Вызывать ее без аргументов не имеет смысла.

Цитата Сообщение от a91 Посмотреть сообщение
Разницу я вижу, а все равно не понимаю почему..
Т.е. нам не нужно писать map elem_p3[list]
можно обойтись map_p3[list] ...
вот это не понял

Цитата Сообщение от a91 Посмотреть сообщение
Частичное применение, почему этот термин называется именно так?
потому что мы применяем функцию не ко всем аргументам, а только к их части
Цитата Сообщение от a91 Посмотреть сообщение
Еще вопрос!
Смотрю :type (.)
(b->c)->(a->b)->a->c
почему не, (b->c)->(a->b)->c
а ты вспомни, что стрелка -> правоассоциативна, и запись (b->c)->(a->b)->a->c абсолютно эквивалентна (b->c)->(a->b)->(a->c). Т.е. оператор композиции (.) принимает две функции, и возвращает функцию, которая применяет к входному аргументу сначала одну функцию, а потом применяет вторую функцию к результирующему значению. Прям как композиция в математике. Естественно, запись (b->c)->(a->b)->c неправильна
Но вообще оператор (.) может быть определен так:
Code
1
2
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g x = f (g x)
или так:
Code
1
2
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
это чтобы прояснить сигнатуру функции. Но на самом деле обе записи эквивалентны (из-за того, что функции в Haskell автоматически каррируются.
Цитата Сообщение от a91 Посмотреть сообщение
Например, есть (square inc ) 3 -- вернет 16
(b->c) это функция square
(a->b) это inc
с это результат 16
ну тут все правильно. Выражение (square . inc) вернет фунцию, которая сначала увеличит переданный аргумент на единицу, а потом возведет полученное выражение в квадрат. Функция-результат выполнения выражения (square . inc) затем применяется к значению 3. Тут, естественно, никакого каррирования нет
Цитата Сообщение от a91 Посмотреть сообщение
Я правильн понимаю, что вот этот пример являюется примером на частичное применение?
и map_plus_3_, и map_plus_3 являются примерами на частичное применение. В обоих определениях мы фиксируем первый аргумент (из двух) для функции map, но для функции map_plus_3 происходит каррирование еще и аргумента для map - в секции (+ 3) мы фиксируем второй аргумент двуместного оператора (функции) (+)
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.01.2012, 16:43
Помогаю со студенческими работами здесь

Тип void как возвращаемое значение функции: что он такое, зачем он нужен, где, когда и как его использовать?
Объясните пожалуйста про Void для оооочень далекого человека. Читаю книгу Шилдта, в принципе всё ясно, всё понимаю и пробую, но вот Void -...

Что где использовать? Где ID, где class?
Здравствуйте. Всегда использовал в <head> <body> ID, а в остальных местах class, но после изучения JS, понял, что нужно менять...

Что за функция bsxfun и как её применять
Объясните пожалуйста что за функция bsxfun, в чем её смысл и как её применять?

Что такое стабы и как правильно их применять
Народ объясните новичку что такое стабы и как правильно их применять. Есть небольшой опыт в создании мок объектов (в MS Fakes их называют...

Что такое оператор сдвига и как его применять
Изучаю С# по книге Герберт Шилдт "Полный справочник по C#". Пример, в книге, на котором показан оператор сдвига для меня мало информативен....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru