2017-01-31 45 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")) 

定义在同级

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

你似乎将功能组合与功能应用混淆在一起。

组合物是高阶函数,它接受两个函数,fg和,兼容的类型的并返回另一个功能 - 它是通过首先施加到g的值,然后应用f到结果计算的功能。 o是一个内置的操作,但如果你想自己定义组成它会是这样的

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

这有型fn : ('a -> 'b) * ('c -> 'a) -> 'c -> 'b(这正是当你在REPL键入(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(FN(项目)=>项目=# “A”)(String.explode “名字”))

这就减少了length [#"a"]并从那里到1

如果你想写自己apply功能你可以这样写:

def apply f x = f x 

这可能会引起你表面上类似于compose但它的类型是根本不同的:fn : ('a -> 'b) -> 'a -> 'b。构成涉及申请,但它不是一回事。