Modeling C ++ concepts using Scala tags

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 ?

+4
source share
1 answer

Change the signature of find to:

 def find[Iter, V, II <: InputIterator[Iter]](first: Iter, last: Iter, x: V)( implicit iterator: II, cmp: EqualityComparable[II#value_type, V]): Iter 

This is probably what you want to express.

Please note that your Scala code does not really match the C ++ code. C ++ find uses Iter::value_type , but Scala uses InputIterator[Iter]#value_type .

+4
source

All Articles