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
. Состав включает в себя приложение, но это не одно и то же.
Вам не хватает параметра в определении композиции; '(f o g) x = f (g x)', или 'f o g = fn x => f (g x)'. – molbdnilo