2012-11-25 21 views
5

在Java 6中可以表達monad的一般情況嗎?注意單詞「一般情況」—儘管單子(即許多特定單子)的許多特定情況是可表示的,但monad的一般情況是不可表達的。在java 6中可以表達monad的一般情況嗎?

這裏的問題是(缺少)Higher-kinded generics in Java;但是,我看到樣本Haskell代碼真正使用類似https://stackoverflow.com/a/877036/1123502(即public class Fix<F extends Fix<F>>)的方式移植到Java。

當然,非類型安全的實現(如使用Object和downcasts)並不重要。

更新:有2個常見monad定義:join-fmap和bind-return。雖然它們在數學上是等價的,但它們可能並不等價,因爲一個定義可以用Java來表達,而另一個定義則不是(然而,在我看來,非等價性不太可能)。所以我的問題涉及兩個定義。底線:是否有人克服了所有障礙,並在Java 6中編寫了「一般情況下」monad?或者,或者,請指出一篇論文或一篇完整的博客文章,或者徹底解釋爲什麼這是不可能的。

+2

參見[* Java中的Monads *](http://logicaltypes.blogspot.com/2011/09/monads-in-java.html)。 – trashgod

+2

@trashgod請注意,在該實現中,'bind'的返回類型是'Monad ' - 而不是'M ',這在Java中是不可能的。因此,如果你有一個從Monad繼承的List類,那麼不能保證在這樣的列表上調用'bind'會產生另一個列表,所以寫'MonadicList strings = myMonadicList.bind( ......)'沒有演員。 ... – sepp2k

+1

...所以在那篇文章中給出的抽象類並不是monad概念的完全正確的實現(雖然它可能和你在Java中獲得的一樣接近正確)。 – sepp2k

回答

5

不是沒有骯髒的鑄造技巧。正如您已經注意到的,Java不支持類型級多態(在斯卡拉土地上也稱爲「高級類型」)。

這裏有一種方法:假設你想實現一個仿函數。您想寫Functor<F<A>>,其中F是例如一個ListMaybe,但這不起作用。但是你可以有一個「基類」Base<X,Y>更高級的東西。 X必須是您的真實課程的「見證」,如ListY是通常的通用參數。現在你的仿函數變得Functor<Base<F,A>>,但希望這個被使用的所有類,需要實現Base<X,Y>

class List<A> implements Base<List.Witness,A> { 
    public class Witness{} 
    ... 
} 

public interface Functor<F> { 
    public <A, B> Base<F, B> map(F1<A, B> fn, Base<F, A> nestedA); 
} 

public class ListFunctor implements Functor<List.Witness> { 
    public <A, B> Base<List.Witness, B> map(F1<A, B> fn, Base<List.Witness, A> nestedA) { 
     ... 
    } 
} 

當然付出的代價是,你得到一個Base<List.Witness,B>,而不是一個List<B>。如果你留在這個更高級的域名中,這可能沒什麼問題,當然你可以有方便的轉換功能,但它仍然不是很好。

有關實現,請參閱我的不那麼嚴肅的項目highJ。請注意,我正在研究一個完全重寫的稍微更方便的版本,它更接近上述示例。

對於嚴重的代碼,請考慮在Scala中編寫這樣的東西(或使用Scalaz)。

相關問題