sml理解功能组合

时间:2017-01-31 00:58:11

标签: sml ml

我试图理解这两者之间的区别;

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

可以调用这个(my_fun“name”将返回1)并且工作正常。我试图理解为什么跟随不起作用

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

sml中函数组成的定义

f o g = f(g(x))

在第二种形式中,我们所做的是(我认为)

length ([#"a"]) 

1 个答案:

答案 0 :(得分:4)

您似乎将功能组合与功能应用混淆。

组合是一个高阶函数,它接受兼容类型的两个函数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应用于该列表是有意义的,这正是您所期望的。

应用程序只是并置,所以你需要做的就是写

length(List.filter(fn(item)=> item =#“a”)(String.explode“name”))

减少到length [#"a"]并从那里减少到1。

如果你想编写自己的apply函数,你会写:

def apply f x = f x

这可能会让您觉得表面上与compose类似,但其类型完全不同:fn : ('a -> 'b) -> 'a -> 'b。组合涉及应用程序,但它不是一回事。