2013-02-24 3 views
3

Я все еще немного смущен про каррирование -Считается ли это карриной функцией?

У меня есть реализация карты в SML, считается ли это карриной функцией?

fun mymap f xs = List.foldr (fn (x, l) => (f x)::l) [] xs; 

Или мне нужно более подробно разъяснять, как обеспечить передачу одного параметра?

fun mymap f = (fn xs => List.foldr (fn (x, l) => (f x)::l) [] xs); 
+0

Да, это действительно так же, как и предыдущее (после обессеривания) –

ответ

4

Да, обе функции являются тонами. На самом деле первая функция является сокращением для второй функции.

2

Адам уже ответил на это, но я хочу научить вас ловить рыбу.

Каждый раз, когда вы вводите функцию в интерпретатор SML, вы получите ответ с сигнатурой типа функции. Вот первый один:

- fun mymap f xs = List.foldr (fn (x, l) => (f x)::l) [] xs; 
val mymap = fn : ('a -> 'b) -> 'a list -> 'b list 

А вот второй один:

- fun mymap f = (fn xs => List.foldr (fn (x, l) => (f x)::l) [] xs); 
val mymap = fn : ('a -> 'b) -> 'a list -> 'b list 

Первое, что мы замечаем, они имеют ту же сигнатуру, что согласуется с утверждением о том, что второй является Обессахаренный формы первого.

Согласно подписи, mymap принимает функцию, которая отображает один тип в другой. Давайте экспериментировать, используя Int.toString:

- mymap Int.toString; 
val it = fn : int list -> string list 

Мы только что сделали частичное применение функции mymap, что возможно только потому, что mymap является кэрри функцию.

Для сравнения, давайте посмотрим, что произойдет с версией mymap, которая не является точной.

- fun mymapUncurried (f,xs) = List.foldr (fn (x, l) => (f x)::l) [] xs; 
val mymapUncurried = fn : ('a -> 'b) * 'a list -> 'b list 

Это то же, что и ваша первая функция, за исключением того, что аргументы заключены в кортеж. В результате сигнатура типа также отличается (см. *?). mymapUncurried принимает 2-кортеж, первый элемент которого имеет тип ('a -> 'b) и второй аргумент которого имеет тип 'a list. Теперь частичное приложение не работает:

- mymapUncurried Int.toString; 
stdIn:9.1-9.28 Error: operator and operand don't agree [tycon mismatch] 
    operator domain: ('Z -> 'Y) * 'Z list 
    operand:   int -> string 
    in expression: 
    mymapUncurried Int.toString 

Однако полное приложение действительно работает. Просто не забудьте передать аргументы в виде кортежа:

- mymapUncurried (Int.toString, [1,2,3]); 
val it = ["1","2","3"] : string list 

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

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