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 函数,它采用兼容类型的两个函数 f
和 g
以及 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
。作文涉及应用,但不是一回事。
我想了解这两者之间的区别;
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 函数,它采用兼容类型的两个函数 f
和 g
以及 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
。作文涉及应用,但不是一回事。