当我最近阅读haskell教材时,因为对于(->)r
类型的applicative functor的实例化的实现有些疑惑(主要是对于函数式编程的不熟悉),所以翻了些stackoverflow的回答解决了我的问题,在此留下一些痕迹。
由于haskell的强类型性质,我们可以通过签名进行简单的推断。\<*>
实际上就是将一个函子中的函数应用于另一个函子中值的过程。
当类型为(->)r
时,<*>
的签名变为((->)r->a->b)->(->)r->a->(->)r->b
,整理一下:r->a->b->r->a->r->b
。这实际上是将一个由参数类型为r的函数返回的函数作用于一个参数类型为r、返回类型为a的函数上的过程,整个过程的返回类型是一个函数,此函数的类型——参数类型为r、返回类型为b)。\
而“一个由参数类型为r的函数返回的函数”实际上就是两个参数的函数而已。
所以现在的问题是如何将两个参数的函数应用于r->a
类型的函数上。
因为我们想要返回一个函数,这个函数参数类型为r,返回类型为b。那我们如何获得一个b类型的值呢?没错,我们有第一部分r->a->b
,因为curry的原因,我们不用顾及第一个参数,我们知道了b类型的来源。但问题是我们同时需要一个a类型的参数来满足a->b
函数。Well,还有第二部分——r->a
函数,我们用这个部分的返回值来满足之前的参数要求。
所以最后的想法很简单:我们返回一个函数,这个函数有一个参数(类型为r),一个返回值(类型为r->b
):
|