Haskell中一些特殊的類型類。
Functor
有些類型是代表計算上下文,比如Maybe的上下文是可能有值或沒有值,對其中的值并不太關心,但我們還需要對Maybe中的值進行計算并保持這種上下文,也就是說如果有值就進行某種計算,如果沒有值就繼續沒有值。這種能夠保持上下文并繼續計算的類型就是Functor。在Haskell中用類型類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的類型參數不能像Haskell那樣是類型構造器,所以fmap的返回值無法定義成F<B>類型。不過可以在Functor的具體實現類中聲明具體的返回類型,比如Maybe的實現,詳細代碼請參考這里?。
class Maybe<A> implements Functor<A, Maybe<?>> {
?? <B> Maybe<B> fmap(Function<A, B> func) {
?? }
}
這種Java實現只能表達函數調用,給人的感覺是fmap就是一個以函數為參數的函數,不能體現fmap函數的lifting特性(看一下Haskell的定義再結合柯里化的理解,不難發現,fmap的輸入是普通函數a->b,返回是新的函數f a -> f b)。更能體現lifting特性的Java定義如下,詳細代碼請參考這里? 和這里??:
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);
?? }
在學習Haskell概念時參考了在線版本的learn you a Haskell?。
在實現Java的Functor接口時參考了文章Functors in Java 。