2013-02-13 3 views
2

Рассмотрим следующую функцию в Scala по умолчанию:Scala: возвращаемое значение параметризованного типа

def wrapMyFunction[A](foo: =>A):A = { 
    try { 
     foo 
    } 
    catch { case e => 
     //Return whatever the "empty" or "default" instance of type A would be, 
     //such as 0, "", None, List(), etc. 
    } 
} 

Учитывая параметр типа А, как я получаю «пустой» или «по умолчанию» значение типа А? Возможно ли это?

+0

Иногда '_' может стоять«значение по умолчанию», однако я не уверен, что если бы работа в случае дженериков. –

ответ

5

Ну, технически, это невозможно, по той простой причине, что нет такой вещи, как значение по умолчанию.

Примеры вы даете все моноидальные нули, поэтому, с Scalaz, вы могли бы написать это:

def wrapMyFunction[A : Zero](foo: =>A):A = { 
    ... 
    catch { case e: Exception => // do not catch all throwables! 
    implicitly[Zero[A]].zero 
    } 
} 

Другой альтернативой было бы создать экземпляр значения. Вы можете использовать ClassManifest или ClassTag (Scala 2.10.0). Например:

def wrapMyFunction[A : scala.reflect.ClassTag](foo: => A): A = { 
    ... 
    catch { case e: Exception => 
    implicitly[scala.reflect.ClassTag[A]].runtimeClass.newInstance.asInstanceOf[A] 
    } 
} 

Это, однако, зависит от существования конструктора без параметров. Использование ClassManifest в значительной степени то же самое.

+0

Вы имеете в виду моноидальное, а не монадическое? Кроме того, я уверен, что «Zero» был удален из семизначного кода - вам нужно будет иметь экземпляр «Monoid». –

+0

@ KristianDomagala я, извините. Да, я слышал, что «Zero» больше не отделен от «Monoid», но Scalaz 7 еще не вышел. –

0

Как сказал Даниэль, это не возможно без ограничения какого-либо типа на A. Что об изменении способа принять значение по умолчанию, либо явно или неявно:

def wrapMyFunction[A](foo: =>A, fallback: =>A):A = ... 

или

def wrapMyFunction[A](foo: =>A)(implicit fallback:A):A = ... 
Смежные вопросы