Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
1

Каррирование или карринг

23.02.2012, 00:38. Показов 4541. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Определение с вики какое-то мутное, кто может объясните пожалуйста поподробнее - что это, для чего и когда применять.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.02.2012, 00:38
Ответы с готовыми решениями:

Карринг без налипания типа
Всем привет! Выполнил карринг стандартной функции printfn аргументом "%O". let pro = printfn...

Каррирование
using System; class MainClass { public static Func<int, int> Sum(int x) { return...

Каррирование
Читаю про каррирование. Почему не работает код из Википедии?: CL-USER 11 > (defun curry(x) ...

Каррирование в JavaScript
Всем привет, вот возник вопрос относительно этой задачи, может подробно объяснить его суть, или...

12
1080 / 1007 / 106
Регистрация: 28.02.2010
Сообщений: 2,889
23.02.2012, 08:49 2
Насколько я понял по википедии - это функция внутри функции.
1
60 / 21 / 2
Регистрация: 23.02.2012
Сообщений: 36
23.02.2012, 09:12 3
Есть функция с n аргументами.
Карринг - преобразание одного вызова с n аргументами в n вызовов с одним аргументом.

Карринг популярен в динамических языках, где функция является присваиваемым объектом.

Функция является присваиваемым объектом, если я могу записать нечто вроде a = x*x, потом вызвать a(5) и получить 25.

Каррингом можно "замораживать" аргументы.

Пусть есть функция inc(a, b), которая увеличивает a на b.

Я могу сделать так (пример на python):

Python
1
2
3
4
5
def binary(f, arg): # f - функция от двух аргументов, arg - число
    return lambda x : f(x, arg) # вернуть функцию, где вместо второго аргумента всегда стоит число
 
a = binary(lambda x, y : x + y, 5) # в функции x + y забить на место второго аргумента число 5 
print a(7) # Теперь а - функция, увеличивающая чило на 5. x + 5 -> 7 + 5 == 12
Запись "lambda x : ..." означает, что я определяю функцию, принимающую x.
lambda x, y : x + y -> функция, принимающая x и y, и складывающая их.

____________
zmartzoft.ru
2
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
23.02.2012, 09:19 4
Тоже наткнулся на эту статью в вики. Единственное применение, которое я ей нашел - https://www.cyberforum.ru/post2461887.html
Ну и насколько я понял, это просто способ писать вместо
C++
1
foo(1, 2, 3)
более извращенный вариант
C++
1
foo(1)(2)(3);
1
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
23.02.2012, 09:57 5
Каррирование — это практика, которая позволяет (в основном, в функциональных ЯП) на основе более общих функций строить их частные версии, фиксируя значения части их аргументов. Основное использование — для передачи в функции высшего порядка. Можно использовать в языках с полноценными замыканиями (т.е. в С не получится, но в C++ можно использовать для этих целей лямбды), либо с помощью костылей (функциональные адаптеры в C++).
1
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
23.02.2012, 10:40 6
Лучший ответ Сообщение было отмечено как решение

Решение

Возьмем такой гипотетический пример: у нас есть функция map_list, которая принимает список (массив) и одноместную функцию и применяет эту функцию к каждому элементу массива. Есть функция plus, которая возвращает сумму двух чисел. Определить функцию, которая будет увеличивать каждый элемент списка на 3, с использованием вышеопределенных функций.
Решение с C (без каррирования):
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
#include <stdlib.h>
 
void map_list(int* array, size_t size, int (*pfunc) (int))
{
    size_t i;
 
    for(i = 0; i < size; ++i)
    array[i] = pfunc(array[i]);
}
 
int plus(int a, int b)
{
    return a + b;
}
 
int plus_3(int a)
{
    return plus(a, 3);
}
 
int main(void)
{
    size_t i;
    int array[5] = {1,2,3,4,5};
            
    map_list(array, 5, plus_3);
 
    for(i = 0; i < 5; ++i)
    printf("%d\n", array[i]);
 
    exit(0);
}
Решение на C++ (каррирование через лямбды):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
 
void map_list(int* arr, size_t size, int (*pfunc) (int))
{
    size_t i;
 
    for(i = 0; i < size; ++i)
    arr[i] = pfunc(arr[i]);
}
 
int plus(int a, int b)
{
    return a + b;
}
 
int main()
{
    int arr[5] = {1,2,3,4,5};
    
    map_list(arr, 5, [=](int a){return plus(a, 3);});
    
    for(size_t i = 0; i < 5; ++i)
    std::cout << arr[i] << std::endl;
}
Решение на C++ («каррирование» через функциональные адаптеры):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <functional>
 
template <typename PFUNC>
void map_list(int* arr, size_t size, PFUNC pfunc)
{
    size_t i;
 
    for(i = 0; i < size; ++i)
    arr[i] = pfunc(arr[i]);
}
 
int plus(int a, int b)
{
    return a + b;
}
 
int main()
{
    int arr[5] = {1,2,3,4,5};
    
    map_list(arr, 5, std::bind1st(std::ptr_fun(plus), 3));
    
    for(size_t i = 0; i < 5; ++i)
    std::cout << arr[i] << std::endl;
}
Common Lisp:
Lisp
1
2
3
4
5
6
7
8
(defun map_list (fun list)
  (reduce (lambda (item acc)
        (cons (funcall fun item) acc))
      list :from-end t :initial-value nil))
 
(defun plus (a b) (+ a b))
 
(format t "~{~d~%~}" (map_list (lambda (a) (plus a 3)) '(1 2 3 4 5)))
Haskell (все функции уже автоматически каррированы, т.е. для того, чтобы получить специализированную версию функции, нужно просто передать ей первые несколько аргументов):
Код
import System.IO (print)
import Control.Monad (mapM_)

map_list :: (a -> b) -> [a] -> [b]
map_list f = foldr (\item acc -> f item : acc) []

plus :: Integral a => a -> a -> a
plus = (+)

main :: IO ()
main = mapM_ print $ map_list (plus 3) [1,2,3,4,5]
Питон:
Python
1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
 
def map_list(fun, lst):
    for i in range(len(lst)):
        lst[i] = fun(lst[i])
    return lst
 
def plus(a, b):
    return a + b
 
print(*map_list(lambda a: plus(a, 3), [1,2,3,4,5]), sep='\n')
PS. в C++, CL, Haskell, Python уже есть функции, аналогичные map_list
6
392 / 284 / 53
Регистрация: 26.12.2009
Сообщений: 874
23.02.2012, 11:09 7
[

Не по теме:

b]Nameless One[/b], вы сами написали все эти примеры?

0
Nameless One
23.02.2012, 11:09
  #8

Не по теме:

Mayonez, да, а что такое?

0
Mayonez
23.02.2012, 11:11
  #9

Не по теме:

круто, знать на таком уровне столько языков

0
Nameless One
23.02.2012, 11:12
  #10

Не по теме:

Mayonez, это уровень Helloworld'ов :D

0
Mayonez
23.02.2012, 11:20
  #11

Не по теме:

Nameless One, я понимаю вашу иронию: чем дольше изучаю с++, тем больше понимаю, что знаю я очень мало, но согласитесь, надпись у вас в статусе "Эксперт C++" все же о чем то говорит (не просто об умении написать hello world)

0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
23.02.2012, 11:52  [ТС] 12
То есть, как я понял, каррирование это использование функции с несколькими аргументами(часть которых мы задаём заранее не переделывая основную функцию, но задавая её частную версию), как аргумента функции высшего порядка?
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
23.02.2012, 11:56 13
Whiteha, можно сказать и так, правда, не обязательно "как аргумента функции высшего порядка" (хотя это и наиболее частый случай использования каррированных функций).
1
23.02.2012, 11:56
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.02.2012, 11:56
Помогаю со студенческими работами здесь

For_each, итераторы, каррирование, шаблоны
Прошу объяснить доступным языком либо дать ссылку на соответствующий материал. 1. Как реализовать...

Для чего нужно каррирование?
Добрый день. Я начал изучать язык F#, дошел до такой фишки как каррирование, вроде понял, что это...

Каррирование, как запомнить предыдущий результат
function sum(a) { var currentSum = a; function f(b) { currentSum += b; return...

Каррирование: что дает, как применять, где использовать?
Здравствуйте! Начал изучать Haskell. С одной стороны формулировку каррирования я понял. f :...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru