haskell中的自然序函数合成

haskell中的自然序函数合成,haskell,functional-programming,Haskell,Functional Programming,我们从右到左都知道和爱/恨组合: (.) :: (b -> c) -> (a -> b) -> a -> c 自然/从左到右合成的“最标准”运算符是什么(如在某种公共库中): (???) :: (a -> b) -> (b -> c) -> a -> c 它概括了值的常识运算符,这些值被视为()中的函数: 在几个图书馆都有 PS:如果没有,该操作员的姓名有哪一方?在数学中,自然作文经常被写成“;”但第二好的名字是什么(&.)可能吗

我们从右到左都知道和爱/恨组合:

(.) :: (b -> c) -> (a -> b) -> a -> c 
自然/从左到右合成的“最标准”运算符是什么(如在某种公共库中):

(???) :: (a -> b) -> (b -> c) -> a -> c
它概括了值的常识运算符,这些值被视为
()
中的函数:

在几个图书馆都有

PS:如果没有,该操作员的姓名有哪一方?在数学中,自然作文经常被写成“;”但第二好的名字是什么<代码>(&.)可能吗

import Control.Arrow
(>>>) :: (a -> b) -> (b -> c) -> a -> c

实际上,
(>>>)
比这更一般,因为它适用于任何类别,而不仅仅是
(>)
函数。不过,它经常用于正向函数合成。

函数合成是函数应用的一种形式
(.)=()
,之所以这样命名是因为它通过函子表示函数应用程序(
($)
)。类似地,我们有反向函数应用程序,
(Data.function.&)
,我们也有通过函子的反向函数应用程序。与
(>>>)
相比,
避免调用
类别
,只调用
函子
,但另一方面,它是对

的一个相对较新的添加,您可以将
infixr 9
操作符定义为
翻转(.)
。这是我通常做的,暴露一些标准操作符。可惜没有一个祝福的前奏曲,我想它会有一个用于这个操作符的语法。哈斯克尔的多种风格使得它不必要的难以阅读。我可以想象,新来者会被这样简单的语法问题拒之门外。你可以隐藏前奏曲
(.)
,然后定义一个重载的
(.)::a->b->c
,查看它的参数类型以决定它的工作方式:实例
a->(a->b)->b
;实例
(a->b)->(b->c)->(a->c)
;实例
(b->c)->(a->b)->(a->c)
。结果类型(或函数依赖项)需要重叠实例和闭合类型族。还需要对复杂的错误消息有很强的承受能力;-)不过,请不要按照@AntC的建议去做。除此之外,没有人会期望
f。g
要有两种可能的解释,它将无法决定
f,g::a->a
的正确顺序,因为
f(gx)
g(fx)
都会进行类型检查首先实际运行
f
,如果
f
实际查看其输入,则只运行
g
。所以
f。g
的顺序实际上是正确的。谢谢。这可能是一个更简单的答案。我以前确实用过它,觉得它应该很方便。为了澄清,我们有
()::函子f=>(a->b)->fa->fb
x->a
对于固定的x,是
a
中的函子,给出
()@(f=x->(a->b)->(x->a)->(x->a)->(x->b)
。在Cat speak中,可表示函子的函数作用是,直到iso,后合成(对于可表示(x->)而言,iso是恒等式)。同样地,对于
()::Functor f=>fa->(a->b)->fb
,它也专门用于
()@(f=x->(a)->(a->b)->(x->b)
在缺点方面,我认为当我们是“客户”时,应该使用非多态代码。“实现者”可能依赖于一般的多态、分类结构,但由于我们作为一个客户不需要它,这些实现细节在理想情况下不应该污染我们的使用。相反,当我们使用它时,它应该是有意义的,因为我们的代码在所有函子实例上确实是多态的。
import Control.Arrow
(>>>) :: (a -> b) -> (b -> c) -> a -> c