У меня есть реализации арифметики на уровне типов, способные выполнять некоторую арифметическую проверку времени компиляции, а именно: <,>,=
двумя способами:
С ними у меня может быть getFoo
функция, которую я могу вызвать следующим образом:
getFoo[_2,_3]
С _2
и_3
- это эквиваленты целочисленных значений 2 и 3 на уровне типов. Теперь в идеале мне бы хотелось, чтобы моя функция getFoo
принимала целочисленные значения в качестве аргументов и пыталась вывести _2
из значения 2
.
Мой план состоял в том, чтобы добавить следующую ассоциированную информацию в базовый класс Nat
:
trait Nat {
val associatedInt: Int
type AssociatedInt = associatedInt.type
}
, чтобы последующие типы были определены как:
type _1 = Succ[_0] {
override val associatedInt: Int = 1
}
, а затем изменитьПодпись getFoo, так что она принимает целое число:
def getFoo(i:Int)(implicit ...)
На основании этого мы будем делать наши арифметические утверждения на уровне типов с типами, связанными с типом AssociatedInt
.То есть что-то типа:
def getFoo(i: Integer)(implicit ev: Nat{type I = i.type } =:= ExpectedType)
Что не работает.Т.е.:
trait Nat {
val i: Integer
type I = i.type
}
type ExpectedType = _1
trait _1 extends Nat {
override val i: Integer = 1
}
def getFoo(i: Integer)
(implicit ev: Nat{type I = i.type } =:= ExpectedType)= ???
getFoo(1) //this fails to prove the =:= implicit.
Если подумать, я не должен был этого ожидать.Поскольку, если мы имеем:
val x : Integer = 1
val y : Integer = 1
type X = x.type
type Y = y.type
def foo(implicit ev: X =:= Y) = 123
foo //would fail to compile.
Т.е. синглтон-типы разных "объектов" с одинаковыми значениями различны.(Я полагаю, причина в том, что в настоящее время в Scala синглтон-типы предназначены для объектов и отличаются от литерального типа )
Так что с этой справочной информацией я хотел бы знать, есть ли какие-либоспособ достижения того, что я пытаюсь сделать, а именно вывод типа a из связанного значения с помощью других методов.