首页 文章

sml理解功能组合

提问于
浏览
4

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

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 回答

  • 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 . 构成涉及应用,但它不是一回事 .

相关问题