2016-05-01 5 views
0

За последние два часа я читал о каррировании в Haskell, и все ресурсы показывают, как функции с несколькими параметрами фактически возвращают другие функции, но не так, как их определения выглядят, так что вот о чем идет речь ,Haskell Currying

Определим функцию:

myFunc :: (Num a) => a -> a -> a 
myFunc x y = x * 2 + x * y 

:t (myFunc 2) печатает Num a => a -> a, то есть функция, которая принимает число, а также выводит номер. Однако, как выглядит определение функции, возвращаемое (myFunc 2)? Подходит ли компилятор x в определении, а новая функция становится чем-то вроде myFunc' y = 2 * 2 + 2 * y?

Как рекурсия обрабатывает карри? Если я определяю функцию

replicate' :: (Integral i, Ord i) => i -> a -> [a] 
replicate' n x 
    | n <= 0 = [] 
    | otherwise = x : replicate' (n - 1) x 

, что функция, возвращаемая (replicate' 3) в контексте (replicate 3) 'a'?

ответ

4

Это replicate' определено в явном кэрри виде:

replicate' :: (Integral i, Ord i) => i -> (a -> [a]) 
replicate' n 
    | n <= 0  = const [] 
    | otherwise = \x -> x : replicate' (n - 1) x 

Итак, replicate' 3 вычисляет выражение

if 3 <= 0 then const [] 
       else \x -> x : replicate' 2 x 

который только

\x -> x : replicate' 2 x 

Если он определен только с “ неявное каррирование ”, то компилятор может или не может вытащить условие n <= 0 из x связывания, поэтому на самом деле вы можете просто в конечном итоге с

\x -> if 3 <= 0 then const [] 
        else \x -> x : replicate' 2 x 
+0

Не могли бы вы объяснить, что '\ x -> x: replicate '2 x' означает? Кроме того, компилятор рассматривает 'myFunc', как я догадался? –

+1

Ум, вы знаете, как работают лямбда-функции, верно? В противном случае, это было бы хорошее время, чтобы прочитать их, они чрезвычайно важны. – leftaroundabout

4

Я думаю, вы смешиваете две разные вещи

  • выделки
  • частичное применение функции

первый является

     ------currying-----> 
     f :: (a,b) -> c      f' :: a -> b -> c 
         <----uncurrying----- 

преобразования функцию, которая принимает tuple аргументов whi ch означает один аргумент двух объединенных вещей - в функцию, которая принимает один аргумент и создает функцию!

Если вы знакомы с линейной алгеброй, это очень похоже на двулинейную функцию, как линейную функцию, которая производит другую линейную функцию.

Принимая во внимание, что приложение частичной функции является следствием явной партизации.

f :: a -> b -> c 

действительно

f :: a -> (b -> c) 

по крайней мере, в Haskell способ определения функций.

+0

Вы уверены? Согласно Википедии, «currying - это метод перевода оценки функции, которая принимает несколько аргументов (или кортеж аргументов) в оценку последовательности функций, каждая с одним аргументом», и согласно (https: // wiki .haskell.org/Partial_application), приложение частичной функции - это когда я создаю функцию, например 'func = replicate 3', которая только дает' replicate' единственный аргумент. Вызов 'func var' будет тиражировать var три раза. –

+0

@ RazvanMeriniuc, в какой части моего ответа вы не согласны - на основе цитируемой статьи Википедии? – epsilonhalbe

+0

Currying не только переводит кортежи, но и несколько аргументов. Второй пример - это приложение currying and partial function, появившееся в контексте, который я представил ранее. –

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

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