2017-01-31 2 views
3

Я пытаюсь понять разницу между этими двумя;sml понимание функции композиции

val my_fun = length o List.filter (fn (item) => item = #"a") o String.explode 

Это может быть вызвано (имя my_fun "будет возвращено 1) и отлично работает. Я пытаюсь понять, почему следующее не работает

length o (List.filter (fn (item) => item = #"a") (String.explode "name")) 

Определение функции состава в SML

f o g = f(g(x)) 

Во второй форме, что мы делаем это (я думаю)

length ([#"a"]) 
+0

Вам не хватает параметра в определении композиции; '(f o g) x = f (g x)', или 'f o g = fn x => f (g x)'. – molbdnilo

ответ

3

You похоже, путают состав функции с применением функции.

Композиция является функцией высшего порядка, который принимает две функции, f и g, совместимых типов и возвращает другую функцию - функцию, которая вычисляется сначала путем применения g к значению, а затем применять f к результату. o встроенный в оператор, но если вы хотите, чтобы определить состав себя, было бы что-то вроде

fun compose (f,g) x = f(g(x)) 

это имеет тип fn : ('a -> 'b) * ('c -> 'a) -> 'c -> 'b (что именно тип вы получаете, когда вы набираете (op o); в РЕПЛ). Обратите внимание, что возвращаемое значение compose равно 'c -> 'b, что является типом функции.

length o List.filter (fn (item) => item = #"a") o String.explode 

имеет прекрасный смысл, поскольку типы совместимы и композиция является право-ассоциативной.

С другой стороны, как вы уже отметить,

length o (List.filter (fn (item) => item = #"a") (String.explode "name")) 

будет эквивалентно

length o [#"a"] 

Это действительно не имеет смысла. Что бы это означало даже для создания функции со списком. Список не является функцией. Имеет смысл до применитьlength к этому списку, чего вы ожидаете.

Применение просто соседство, поэтому все, что вам нужно будет сделать, это написать

длины (List.filter (п (п) => пункт = # "а") (String.explode "имя"))

Который сводится к length [#"a"] и оттуда к 1.

Если вы хотите, чтобы написать свою собственную apply функцию можно было бы написать:

def apply f x = f x 

Это может поразить вас как внешне похожим на compose, но его тип радикально отличается: fn : ('a -> 'b) -> 'a -> 'b. Состав включает в себя приложение, но это не одно и то же.

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