Форум программистов, компьютерный форум CyberForum.ru

Каррирование или карринг - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.78
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
23.02.2012, 00:38     Каррирование или карринг #1
Определение с вики какое-то мутное, кто может объясните пожалуйста поподробнее - что это, для чего и когда применять.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.02.2012, 00:38     Каррирование или карринг
Посмотрите здесь:

C++ Книги или справочники для опытных(или проффесиональных) программистов!
Вложенные CMap или CArray-объекты. Ошибка компилятора или неправильная работа. C++
Контроль точности Рунге-Кутта (3 или 4 порядка) или Эйлера. C++
Имеет ли смысл продолжать учить с++ или попробовать перейти в с# или java? C++
C++ Создать программу при нажатии на кнопку м или ж выводились муржской или женский пол.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Евгений М.
1033 / 974 / 53
Регистрация: 28.02.2010
Сообщений: 2,817
Завершенные тесты: 2
23.02.2012, 08:49     Каррирование или карринг #2
Насколько я понял по википедии - это функция внутри функции.
samdavydov
59 / 20 / 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
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
23.02.2012, 09:19     Каррирование или карринг #4
Тоже наткнулся на эту статью в вики. Единственное применение, которое я ей нашел - Написать программу чтобы выводила надпись Hello world
Ну и насколько я понял, это просто способ писать вместо
C++
1
foo(1, 2, 3)
более извращенный вариант
C++
1
foo(1)(2)(3);
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.02.2012, 09:57     Каррирование или карринг #5
Каррирование — это практика, которая позволяет (в основном, в функциональных ЯП) на основе более общих функций строить их частные версии, фиксируя значения части их аргументов. Основное использование — для передачи в функции высшего порядка. Можно использовать в языках с полноценными замыканиями (т.е. в С не получится, но в C++ можно использовать для этих целей лямбды), либо с помощью костылей (функциональные адаптеры в C++).
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
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
Mayonez
 Аватар для Mayonez
379 / 271 / 20
Регистрация: 26.12.2009
Сообщений: 875
23.02.2012, 11:09     Каррирование или карринг #7
[

Не по теме:

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

Nameless One
23.02.2012, 11:09
  #8

Не по теме:

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

Mayonez
23.02.2012, 11:11
  #9

Не по теме:

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

Nameless One
23.02.2012, 11:12
  #10

Не по теме:

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

Mayonez
23.02.2012, 11:20
  #11

Не по теме:

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

Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
23.02.2012, 11:52  [ТС]     Каррирование или карринг #12
То есть, как я понял, каррирование это использование функции с несколькими аргументами(часть которых мы задаём заранее не переделывая основную функцию, но задавая её частную версию), как аргумента функции высшего порядка?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.02.2012, 11:56     Каррирование или карринг
Еще ссылки по теме:

При вводе элементов массива выводить их тип (или int или float) C++
C++ Количество нулевых, или положительных, или отрицательных элементов в двумерном массиве
C++ Написать программу вычисления площади треугольники или квадрата или трапеции

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

Или воспользуйтесь поиском по форуму:
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
23.02.2012, 11:56     Каррирование или карринг #13
Whiteha, можно сказать и так, правда, не обязательно "как аргумента функции высшего порядка" (хотя это и наиболее частый случай использования каррированных функций).
Yandex
Объявления
23.02.2012, 11:56     Каррирование или карринг
Ответ Создать тему
Опции темы

Текущее время: 19:22. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru