将可扩展数组索引(Ix和系列)移植到Java 虽然我认为自己是一个较低的中间Haskeller(理解RankNTypes,但与箭)PROC“符号”斗争,我在java上更为新手。尽管如此,我认为在Java中有一件事是我不能缺少的,那就是类似于Ixtype类和Haskell灵活索引的数组。我开始做我自己的,但我正好遇到了我自己缺乏经验的问题。有人能给我一些关于这项任务的建议或建议吗?我是完全错了,还是我的想法正确?JavaSE7平台是否已经有了我不知何故错过的东西?其他人已经做过了吗

将可扩展数组索引(Ix和系列)移植到Java 虽然我认为自己是一个较低的中间Haskeller(理解RankNTypes,但与箭)PROC“符号”斗争,我在java上更为新手。尽管如此,我认为在Java中有一件事是我不能缺少的,那就是类似于Ixtype类和Haskell灵活索引的数组。我开始做我自己的,但我正好遇到了我自己缺乏经验的问题。有人能给我一些关于这项任务的建议或建议吗?我是完全错了,还是我的想法正确?JavaSE7平台是否已经有了我不知何故错过的东西?其他人已经做过了吗,java,arrays,haskell,porting,Java,Arrays,Haskell,Porting,我有以下界面模拟Ix类型类: public interface Ix<T extends Ix<T>> { int indexIn(IxRange<T> range); boolean isIn(IxRange<T> range); boolean isFirstIn(IxRange<T> range); boolean isLastIn(IxRange<T> range); T ne

我有以下界面模拟
Ix
类型类:

public interface Ix<T extends Ix<T>> {
    int indexIn(IxRange<T> range);
    boolean isIn(IxRange<T> range);
    boolean isFirstIn(IxRange<T> range);
    boolean isLastIn(IxRange<T> range);
    T nextIndexIn(IxRange<T> range);
    T prevIndexIn(IxRange<T> range);
    IxRange<T> maxRange();
}
然后我有一节课是这样开始的:

public class FlexArray<I extends Ix<I>,E> extends AbstractList<E> implements Cloneable
公共类FlexArray扩展AbstractList实现可克隆
这是我遇到最多麻烦的地方,主要是,但不是唯一的,因为首先需要一个实例来调用
maxRange()
(gah!)。我还为实现
Ix
接口的常见类型提供了几个包装器类,但这是一个辅助问题


总而言之,我正在寻找关于如何继续的建议,如果可能的话,还有如何重构
Ix
以摆脱
maxRange()
并用更好的东西取代它。关于这项任务的一般想法也是受欢迎的,但不是这个问题的重点。

我的方法是使用“第一类类型类”,也称为“概念模式”,你不会得到推理,它并不像直接使用oo接口那样干净,但在需要二进制方法之类的东西时更有意义。您可以完全避免“奇怪地重复出现的泛型模式”(
Ix
),它简化了事情,但代价是需要手动传递字典

public interface Ix<A>{
   public List<A> range(A start,A end);
   public int index(A start,A end,A el);
   public boolean inRange(A start,A end,A el);
   public int rangeSize(A start,A end);
}
公共接口Ix{
公共列表范围(开始、结束);
公共整数索引(起点、终点、el);
范围内的公共布尔值(起点、终点、el);
公共整数范围大小(开始、结束);
}
要使用它,只需像在Haskell中一样创建“实例”

public class IxInteger extends Ix<Integer>{
    //use the singelton pattern 
    private static IxInteger instance = new IxInteger();
    public static IxInteger getInstance(){
       return instance;
    }
    private IxInteger(){
       //most likely doesn't need to do anything
    }
    //implement the typeclass
    public List<Integer> range(Integer start,Integer end){
       List<Integer> list = new ArrayList<Integer>(end-start);
       for(int i = start; i < end; i++){
           list.add(i);
       }
       return list;
    }
    ...
}
公共类IxInteger扩展了Ix{
//使用singelton模式
私有静态IxInteger实例=新IxInteger();
公共静态IxInteger getInstance(){
返回实例;
}
私有IxInteger(){
//很可能不需要做任何事情
}
//实现typeclass
公共列表范围(整数开始、整数结束){
列表列表=新的ArrayList(结束-开始);
for(int i=start;i
然后,你只要随时把字典递过来就行了

public Foo ixFoo<A>(args..,Ix<A> ixDict){
   // do stuff
   ...
   // and when you need the dictionary
   myList = ixDict.range(start,end);
   ...
}
public Foo-ixFoo(args..,Ix-ixDict){
//做事
...
//当你需要字典的时候
myList=ixDict.range(开始、结束);
...
}


编辑:一个问题是,在翻译代码时,有时你会做一些愚蠢的事情。在Haskell中,
[a]
被用作iterable集合的一种通用接口。这在严格的语言中并不起作用。因此,在我的代码中应该用迭代器代替
List
。在这种时候,最好保持懒惰

那么,像你现在这样践踏
List
的一两个方法可以吗?我一直被告知这是一个禁忌。:/我不会为此担心,因为你不太可能同时拥有
列表
Ix
实例。我不知道这是否会有帮助,但Frege(code.google.com/p/Frege)可以将源自Haskell 98/2010的源代码翻译成Java。生成的代码仍然依赖于Frege运行时,但可能给出了一个方法。奥托,如果你不想懒惰,那也没什么帮助。
public Foo ixFoo<A>(args..,Ix<A> ixDict){
   // do stuff
   ...
   // and when you need the dictionary
   myList = ixDict.range(start,end);
   ...
}