sml理解函数组合

sml understanding function compositions

我想了解这两者之间的区别;

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

这个可以调用(my_fun "name" 将 return 1)并且工作正常。我想了解为什么以下内容不起作用

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

sml中函数组合的定义

f o g = f(g(x))

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

length ([#"a"]) 

您似乎混淆了函数组合和函数应用。

Composition 是一个 higher-order 函数,它采用兼容类型的两个函数 fg 以及 return 另一个函数 -- 被计算的函数首先将 g 应用于一个值,然后将 f 应用于结果。 o 是一个 built-in 运算符,但如果您想自己定义组合,它会像

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

它的类型为 fn : ('a -> 'b) * ('c -> 'a) -> 'c -> 'b(这正是您在 REPL 中键入 (op o); 时得到的类型)。注意compose的return值为'c -> 'b,是函数类型

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

非常合理,因为类型兼容并且组合是 right-associative.

另一方面,正如您已经注意到的,

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

相当于

length o [#"a"]

这真的没有意义。用列表组合函数甚至意味着什么。列表不是函数。 apply 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。作文涉及应用,但不是一回事。