Scala: типизированный метод, возвращающий подтип

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

У меня есть абстрактный класс

abstract class IsoBoxReader

У меня есть производный класс

class FileTypeBoxReader( val box, val isoReader ) extends IsoBoxReader

Я хочу сделать что-то подобное, и я не уверен, что это возможно:

def recognize[ T <: IsoBoxReader ]( box ): (IsoReader) => T =
{
    box.boxType match {
      case "ftyp" => ( isoReader: IsoReader ) => new FileTypeBoxReader( box, isoReader )
      case _ => // return some other box type
    }
}

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

Некоторые из вас могли догадаться, что я пытаюсь анализировать медиа-файлы Iso на основе спецификации ISO. Я делаю это в основном для опыта, и это кажется интересной проблемой объектно-ориентированного и функционального дизайна.

Чтобы создать специальный блок чтения, мне нужен базовый блок, который представляет собой информацию заголовка, и объект чтения, который в основном выполняет чтение определенного файла. Я хочу написать функцию, которая с учетом блока (с типом блока) я получаю частично примененную функцию, которая возвращает подтип IsoBoxReader. Таким образом, вызывающий объект может создать фактический экземпляр со своей версией IsoReader (чтение файла, объект с отслеживанием состояния). Компилятор жалуется на совпадение с шаблоном, в частности, на несоответствие типов.

Он говорит, что нашел FileTypeBoxReader, но ожидал T

Однако, исходя из аргумента Type, не является ли FileTypeBoxReader допустимым возвращаемым значением, поскольку он является подтипом IsoBoxReader?


person Kartik Aiyer    schedule 20.02.2013    source источник
comment
Где определяется boxType? Каково его определение? Пожалуйста, создавайте как минимум автономные фрагменты кода.   -  person Randall Schulz    schedule 20.02.2013
comment
boxType - это строка... это просто селектор...   -  person Kartik Aiyer    schedule 20.02.2013


Ответы (1)


Попробуй это:

def recognize( box ): (IsoReader) => IsoBoxReader =
{
    box.boxType match {
      case "ftyp" => ( isoReader: IsoReader ) => new FileTypeBoxReader( box, isoReader )
      case _ => // return some other box type
    }
}

def recognize[ T <: IsoBoxReader ]( box ): (IsoReader) => T должно работать для любого конкретного типа, являющегося подтипом IsoBoxReader, что очевидно невозможно в данной ситуации. Другими словами, поскольку фактический тип определяется во время выполнения box.boxType, на сайте вызова recognize() тип T не может быть определен статически. Так что здесь неправильно использовать параметр типа T.

person Jiangzhou    schedule 20.02.2013
comment
Ваш [IsoBoxReader] должен быть удален из подписи, так как он неверен. - person Samuel Tardieu; 20.02.2013
comment
Это была моя ошибка. Спасибо. - person Jiangzhou; 20.02.2013
comment
Спасибо... Похоже, мне лучше вернуться и узнать больше о типизированных методах... теперь то, что вы говорите, имеет для меня смысл... - person Kartik Aiyer; 20.02.2013