【问题标题】:sml understanding function compositionssml 理解函数组成
【发布时间】:2017-01-31 00:58:10
【问题描述】:

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

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"]) 

【问题讨论】:

  • 您在组合定义中缺少参数; (f o g) x = f(g x),或f o g = fn x => f (g x)

标签: sml ml


【解决方案1】:

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

Composition 是一个高阶函数,它接受两个兼容类型的函数 fg 并返回另一个函数——该函数通过首先将 g 应用于一个值然后应用f 结果。 o 是一个内置运算符,但如果你想自己定义组合,它会类似于

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

this 的类型为 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。组合涉及应用,但不是一回事。

【讨论】:

    猜你喜欢
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    相关资源
    最近更新 更多