2015-08-11 5 views
0

Учитывая следующее:Параметры типа и тип алгебраических данных?

scala> sealed trait Parent 
defined trait Parent 

scala> case object Boy extends Parent 
defined object Boy 

scala> case object Girl extends Parent 
defined object Girl 

, а затем метод:

scala> def foo[A <: Parent](x: Parent): A = { 
    | if(true) Boy else Girl 
    | } 
<console>:14: error: type mismatch; 
found : Boy.type 
required: A 
      if(true) Boy else Girl 
       ^
<console>:14: error: type mismatch; 
found : Girl.type 
required: A 
      if(true) Boy else Girl 
          ^

Во время компиляции, это не известно, что Boy и Girl являются единственными подклассы Parent, i.e. A?

+5

'Foo' не может возвращать' Ā', так что выбирается клиентом, наиболее конкретный тип возвращается в 'Parent'. Что бы вы ожидали от 'foo [Girl]'? – Lee

+0

"из" Parent', то есть 'A'" - вот где ваша логика пошла не так. 'Parent' * не *' A'. Это супертип «А». – dcastro

ответ

0

Проверьте это:

def foo[S >: Parent](p:Parent):S = if(true) Boy else Girl 
0

Возможно определить метод с A >: Parent вместо A <: Parent показывает более ясно, что случилось с вашим кодом:

scala> def foo[A >: Parent](x: Parent): A = { if(true) Boy else Girl } 
foo: [A >: Parent](x: Parent)A 

scala> foo[Parent](Boy) 
res1: Parent = Boy 

scala> foo[Object](Boy) 
res2: Object = Boy 

И.Э. res2 является Object, тогда как res1 является Parent.

Как Ли упоминалось в комментариях, в своем коде вы бы ожидать, что она будет называться с A быть Girl.type поэтому подпись затем стать: foo[Girl.type](x: Parent): Girl.type но возвращаемый тип вашей реализации не Girl.type.

Вот вариант кода с помощью A <: Parent, что делает работу:

scala> def foo[A <: Parent](x: A): A = x 
foo: [A <: Parent](x: A)A 

scala> foo[Boy.type](Boy) 
res3: Boy.type = Boy 
Смежные вопросы