在論文«Type Classes as Objects and Implicits»中有一些使用Scala特徵的例子,例如C++概念和Haskell類型類。我試着寫類似InputIterator
概念和find
功能斯卡拉:使用Scala特徵對C++概念進行建模
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;
}
我不知道我理解正確的特徵。但仍...有InputIterator
特質Scala編寫的(或者更確切地說 - 這是簡單的模擬與方法find
功能使用):
trait InputIterator[Iter] {
type value_type
def <(a: Iter, b: Iter): Boolean
def ++(it: Iter): Unit
def *(it: Iter): value_type
}
EqualityComparable
是明確的:
trait EqualityComparable[S, T] {
def ==(s: S, t: T): Boolean
def !=(s: S, t: T): Boolean = !(s == t)
}
但是我們應該用find
做什麼?我想編寫這樣的事:
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
}
但它會導致錯誤«非法方法依賴型»。而我不知道如何「抽取」其他方式抽象類型value_type
。因此,作爲一個結果,我有這樣的代碼:
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)
}
而不是抽象類型,我們用類型參數VT
在def find[Iter, VT, V]
。
所以問題是:如何做得更好?是否可以使用抽象類型value_type
而無需附加類型參數VT
?
不太瞭解C++,所以,爲什麼InputIterator不僅僅是一個Iterator? – pedrofurla 2013-02-21 11:35:03
在C++中'Iterator'是迭代器的基類,它沒有任何方法。 'InputIterator'允許你遍歷集合(僅用於讀取)。 – juliet 2013-02-21 11:46:47