2015-05-19 3 views
2

Так вот вопрос, который я спросил перед: Scala: Function returning an unknown typeФункция возвращает динамический тип

Это очень сильно следить за этим.

Ранее я задал вопрос о добавлении типов номеров и возвращении одного с большей точностью. На это ответили классы типов для правил Weak Conformance и указав там тип. Например, WeakConformance [Int, Double] указывает, что будет возвращен double.

Однако при добавлении сложности границ это создает проблемы. Скажем, я хотел сделать класс типа для добавления двух байтов вместе:

class ByteisAddable extends Addable[Byte, Byte] { 
    def add(x: Byte, y: Byte): ? = { 
    if(Byte.MaxValue - x < y) 
     // this is an int 
     x + y 
    else 
     // this is a byte 
     (x + y).toByte 
    } 
} 

Тип класса WeakConformance [Byte, Byte] не может просто определяет один тип, потому что это может быть Int или Byte. То есть вычисление добавления значений должно иметь место до того, как можно указать тип возвращаемого значения. Например, два байта: 10 + 10 должны возвращать байт значения 20. Но два байта: 100 + 100 должны возвращать int или переполнять Byte.MaxValue.

Есть ли лучший способ сделать это? Или есть способ указать тип после вычисления?

ответ

4

То, о чем вы просите, является своего рода Dependent Type System. Только несколько языков поддерживают такие системы типов, и это активная область исследований.

Вы можете вернуть динамический тип из метода с помощью подтипов:

def add(x: Byte, y: Byte): java.lang.Number = { 
    if(Byte.MaxValue - x < y) 
    new java.lang.Integer(x + y) 
    else 
    new java.lang.Byte(x + y) 
} 

Однако, я предполагаю, что это не то, что вы хотите. Я предполагаю, что вы хотите, чтобы тип статического возврата определялся динамически.

И это как раз проблема: у вас не может быть статический тип, основанный на значениях времени выполнения вашей программы. Поэтому, чтобы гарантировать, что add(Byte, Byte) возвращает еще один Byte (без переполнения), вам нужно будет закодировать какое-то суждение в вашей системе типов, говоря, что сумма типов не переполняется. И для этого вам нужны зависимые типы. Фиктивным примером зависимого типа является Byte[x < 30], что означает Byte меньше 30 (обозначение полностью произвольное).

Поэтому, если вы не хотите внедрить свою собственную систему зависимого типа в Scala (что явно выходит за рамки SO-ответа), мне жаль говорить вам, что вам не повезло.

Посмотрите на this post, чтобы узнать, какой вид жаркого вам достается :)

Смежные вопросы