我想了解这两者之间的区别;
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 回答
您似乎将功能组合与功能应用混淆 .
组合是一个高阶函数,它接受兼容类型的两个函数
f
和g
,并返回另一个函数 - 通过首先将g
应用于某个值然后将f
应用于结果来计算的函数 .o
是一个内置的运算符,但是如果你想自己定义组合,那就像是这个类型为
fn : ('a -> 'b) * ('c -> 'a) -> 'c -> 'b
(这正是您在REPL中键入(op o);
时获得的类型) . 请注意,compose
的返回值是'c -> 'b
,这是一种函数类型 .因为类型兼容并且组合是正确关联的,所以非常有意义 .
另一方面,正如您已经注意到的那样,
相当于
这真的不是一个功能 . 将
length
应用于该列表确实有意义,这正是您所期望的 .应用程序只是并置,所以你需要做的就是写
length(List.filter(fn(item)=> item =#“a”)(String.explode“name”))
从而减少到
length [#"a"]
并从那里减少到1 .如果你想编写自己的
apply
函数,你会写:这可能会让你表面上看起来与
compose
类似,但它的类型完全不同:fn : ('a -> 'b) -> 'a -> 'b
. 构成涉及应用,但它不是一回事 .