2015-10-05 4 views
1

Я не уверен, что формулировка вопроса была подходящей, поэтому я уточню.Scala использует зависимый тип в сигнатуре типа функции?

sealed trait RedisKey[A] { 
    type valueType = A 
    def name: String 
} 
case object FirstName extends RedisKey[String] { val name = "first_name" } 
case object Age extends RedisKey[Int] { val name = "age" } 

trait Redis { 
    def fetch(key: RedisKey)// : key.valueType 
} 

Мне нужно ограничить тип возвращаемого fetch на RedisKey «s зависимого типаvalueType (не уверен, если это правильный термин). Но, очевидно, вышеупомянутое не работает, так как мне нужен конкретный экземпляр RedisKey, прежде чем я получу доступ к его зависимому типу.

Можно ли добиться этого каким-либо образом?

ответ

6

Вы можете сделать это с зависимым типом тоже:

sealed trait RedisKey { 
    type valueType 
    def name: String 
} 
case object FirstName extends RedisKey { type valueType = String; val name = "first_name" } 
case object Age extends RedisKey { type valueType = Int; val name = "age" } 

trait Redis { 
    def fetch(key: RedisKey): key.valueType 
} 
(null: Redis).fetch(Age): Int 
(null: Redis).fetch(FirstName): String 

Последние две строки есть, чтобы проверить тип возвращаемого значения метода в REPL.

+0

HUH? мы можем ссылаться на экземпляр подписи? Я подтвердил, что это работает, но как? Это из-за наличия зависимого типа в 'trait', который позволяет это? Не могли бы вы назвать меня официальной спецификацией? –

+0

Элемент 'RedisKey' содержит элемент абстрактного типа (' valueType'). Метод 'fetch' использует типы singleton в своем обратном типе ([spec] (http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#singleton-types)). – planetenkiller

1

Оказалось, что через 5 минут после публикации этого вопроса я понял, что переусердствовал.

Следующие работы без взлома зависимого типа.

sealed trait RedisKey[A] { 
    def name: String 
} 
case object FirstName extends RedisKey[String] { val name = "first_name" } 
case object Age extends RedisKey[Int] { val name = "age" } 

trait Redis { 
    def fetch[A](key: RedisKey[A]): A 
} 
Смежные вопросы