Haskell中一些特殊的類(lèi)型類(lèi)婚瓜。
Functor
有些類(lèi)型是代表計(jì)算上下文,比如Maybe的上下文是可能有值或沒(méi)有值刑棵,對(duì)其中的值并不太關(guān)心巴刻,但我們還需要對(duì)Maybe中的值進(jìn)行計(jì)算并保持這種上下文,也就是說(shuō)如果有值就進(jìn)行某種計(jì)算蛉签,如果沒(méi)有值就繼續(xù)沒(méi)有值胡陪。這種能夠保持上下文并繼續(xù)計(jì)算的類(lèi)型就是Functor。在Haskell中用類(lèi)型類(lèi)Functor表示
class Functor f where
?? fmap :: (a -> b) -> f a -> fb
用Java的接口表示
interface Functor<A, F extends Functor<?, ?>> {
?? <B> ? F fmap(Function<A, B> func);
}
Java的類(lèi)型參數(shù)不能像Haskell那樣是類(lèi)型構(gòu)造器碍舍,所以fmap的返回值無(wú)法定義成F<B>類(lèi)型柠座。不過(guò)可以在Functor的具體實(shí)現(xiàn)類(lèi)中聲明具體的返回類(lèi)型,比如Maybe的實(shí)現(xiàn)片橡,詳細(xì)代碼請(qǐng)參考這里?妈经。
class Maybe<A> implements Functor<A, Maybe<?>> {
?? <B> Maybe<B> fmap(Function<A, B> func) {
?? }
}
這種Java實(shí)現(xiàn)只能表達(dá)函數(shù)調(diào)用,給人的感覺(jué)是fmap就是一個(gè)以函數(shù)為參數(shù)的函數(shù)捧书,不能體現(xiàn)fmap函數(shù)的lifting特性(看一下Haskell的定義再結(jié)合柯里化的理解吹泡,不難發(fā)現(xiàn),fmap的輸入是普通函數(shù)a->b经瓷,返回是新的函數(shù)f a -> f b)爆哑。更能體現(xiàn)lifting特性的Java定義如下,詳細(xì)代碼請(qǐng)參考這里? 和這里??:
interface Functor2<A> {
?? <B> Functor2<B> apply(Function<A, B> fn);
?? static <A, B> Function<Functor2<A>, Functor2<B>> fmap(Function<A, B> fn) {
????? return fa -> fa.apply(fn);
?? }
在學(xué)習(xí)Haskell概念時(shí)參考了在線(xiàn)版本的learn you a Haskell?舆吮。
在實(shí)現(xiàn)Java的Functor接口時(shí)參考了文章Functors in Java 揭朝。