There are several examples of using Scala features, such as C ++ concepts and Haskell type classes in the document βType of classes as objects and implicationsβ . I am trying to write something like the concept of InputIterator and find in Scala:
concept InputIterator<typename Iter> { typename value_type; value_type operator*(Iter); ... }; template<typename Iter, typename V> requires InputIterator<Iter> && EqualityComparable<Iter::value_type, V> Iter find(Iter first, Iter last, V v) { while (first < last && *first != v) ++first; return first; }
I'm not sure I understand the features correctly. But still ... There is a trait of InputIterator written in Scala (or, more precisely, a simplified analogue with the methods used in the find function):
trait InputIterator[Iter] { type value_type def <(a: Iter, b: Iter): Boolean def ++(it: Iter): Unit def *(it: Iter): value_type }
EqualityComparable clearly:
trait EqualityComparable[S, T] { def ==(s: S, t: T): Boolean def !=(s: S, t: T): Boolean = !(s == t) }
But what do we do with find ? I would like to write something like this:
def find[Iter, V](first: Iter, last: Iter, x: V)(implicit iterator: InputIterator[Iter], cmp: EqualityComparable[iterator.value_type, V]): Iter = { while (iterator.<(first, last) && cmp.!=(iterator.*(first), x)) iterator.++(first) first }
But this causes the "illegal dependent method type" error. And I do not know how to "extract" the abstract type value_type another way. So I have this code:
trait EqualityComparable[S, T] { def ==(s: S, t: T): Boolean def !=(s: S, t: T): Boolean = !(s == t) } trait InputIterator[Iter] { type value_type def <(a: Iter, b: Iter): Boolean def ++(it: Iter): Unit def *(it: Iter): value_type } trait VTInputIterator[Iter, VT] extends InputIterator[Iter] { type value_type = VT } class ArrayListIterator[T](a: ArrayList[T], i: Int) { val arr: ArrayList[T] = a var ind: Int = i def curr(): T = arr.get(ind) def ++(): Unit = { ind += 1 } override def toString() = "[" + ind.toString() + "]" } class InputIterArrList[T] extends VTInputIterator[ArrayListIterator[T], T]{ def <(a: ArrayListIterator[T], b: ArrayListIterator[T]) = { if (a.arr == b.arr) a.ind < b.ind else throw new IllegalArgumentException() } def ++(it: ArrayListIterator[T]): Unit = it.++() def *(it: ArrayListIterator[T]) = it.curr() } object TestInputIterator extends Application{ def find[Iter, VT, V](first: Iter, last: Iter, x: V)(implicit iterator: VTInputIterator[Iter, VT], cmp: EqualityComparable[VT, V]): Iter = { while (iterator.<(first, last) && cmp.!=(iterator.*(first), x)) iterator.++(first) first } implicit object EqIntInt extends EqualityComparable[Int, Int] { def ==(a: Int, b: Int): Boolean = { a == b } } implicit object inputIterArrListInt extends InputIterArrList[Int]{} val len = 10; var arr: ArrayList[Int] = new ArrayList(len); for (i: Int <- 1 to len) arr.add(i) var arrFirst = new ArrayListIterator(arr, 0) var arrLast = new ArrayListIterator(arr, len) var r = find(arrFirst, arrLast, 7) println(r) }
Instead of an abstract type, we used a parameter of type VT in def find[Iter, VT, V] .
So the question is: how can this be done better? And is it possible to use the abstract type value_type without an additional parameter of type VT ?