一招鲜,吃遍天

在Haskell等语言中,有datatype generic的概念:对于各种各样的ADT,都可以表示成一系列的Sum type 跟 Product type(因为这是ADT的定义),所以理论上,只要你能处理ADT的通用定义,你就能写一个对所有ADT适用的函数。其实这就是当你写deriving Show/Eq/Ord的时候发生的情况。generic,又称polytypic programming,就是把这理论变成现实的特性。注意这跟type generic是两码事。

这里面的Notable Work包括Scrap Your Boilerplate:把一定的类型信息塞到运行时,(Typable),然后就可以对某个类型做一种东西,而其他类型不变。然后可以写个高阶函数,对该类型做action,其他类型(wrapper,比如list/sum/either/whatever)就默认map进去,这样就可以给[Either [Double] Double]之类的type里面的所有Double翻倍,或者加起来返回。

GHC.generic做的是另外的东西,把一个类型表现成Sum type/Product type/Metadata(我们称作Rep),然后所有ADT都可以转化成这类型。然后加上把某类型变成它Rep的方法,就可以写function on all ADT,然后也可以写deriving等

True Sum Of Product就在GHC.generic上面做了层抽象,不用ADT来表示Rep,而是表示成[[*]] (类型的列表的列表)。然后有多参Product/Sum (可以想象成NProduct :: [*] -> *,其实具体情况复杂点),就可以直接组合/Map/Fold Product/Sum来完成generic programming,而无需在GHC.generic中递归,因为Sum type里面可能有Product type,然后里面再有Sum type。。。而这在True Sum Of Produt中不可能发生

然后还有Generic Generic Programming,因为有很多套Generic Library,每套都不一样,所以就搞出了个东西unify之。。。什么鬼


编辑于 2018-01-06 17:05

文章被以下专栏收录