這是我第一次嘗試:如何在Java中實現Haskell的IO類型?
import java.util.function.*;
import java.util.ArrayList;
public class IO<A> {
private Function<World,Tuple<World,A>> transform;
private class World {
private ArrayList<String> stdin;
private ArrayList<String> stdout;
public World() {
this.stdin = new ArrayList<String>();
this.stdout = new ArrayList<String>();
}
}
private class Tuple<F,S> {
public F fst;
public S snd;
public Tuple(F fst, S snd) {
this.fst = fst;
this.snd = snd;
}
}
public IO(Function<World,Tuple<World,A>> transform) {
this.transform = transform;
}
public IO<A> pure(A a) {
return new IO<A>(r -> new Tuple<World,A>(r,a));
}
public <B> IO<B> bind(IO<A> io, Function<A,IO<B>> f) {
return new IO<B>(r -> {
Tuple<World,A> result = io.transform.apply(r);
IO<B> ioB = f.apply(result.snd);
return ioB.transform.apply(result.fst);
});
}
}
但是當我嘗試編譯此我得到以下錯誤:
IO.java:29: error: incompatible types: IO<B>.World cannot be converted to IO<A>.World
Tuple<World,A> result = io.transform.apply(r);
^
where B,A are type-variables:
B extends Object declared in method <B>bind(IO<A>,Function<A,IO<B>>)
A extends Object declared in class IO
我不明白的是世界級的具有無關係類型變量,但javac認爲它確實。我究竟做錯了什麼?
我不太清楚你的目標是有什麼用,但我認爲你錯誤地認爲'世界'的目的,這不是考慮'IO'單子的最佳方式。無論哪種方式,您定義的「世界」意味着「變換」可以添加到輸入並從輸出中移除,這可能是不希望的行爲。 –
目標是向Java開發人員介紹Haskell。我認爲純粹的IO是Haskell最酷的概念,所以我只是製作一個簡單的IO模型。我同意,雖然標準清單應該只讀。 –
我不是Java開發人員,但我不明白這麼毛茸茸的東西可能是介紹Haskell的'IO'類型的好方法。爲此,我會提出一種「操作monad」方法,其中'IO a'被視爲由原始命令和延續組成的數據結構。 – dfeuer