2013-02-13 136 views
2

考虑斯卡拉以下函数返回默认值:斯卡拉:参数化类型

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. 
    } 
} 

给定类型参数,我怎么获得A类的“空”或“默认”值?它甚至有可能吗?

+0

有时'_'可以代表“默认值”但是我不知道是否会在仿制药的情况下工作。 – 2013-02-13 05:46:05

回答

5

那么,从技术上说,这是不可能的,因为简单的原因,没有这样的事情作为“默认”值。

你给的示例都monoidal零,因此,与Scalaz,你可以这样写:

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

另一种方法是,以实例的值。您可以使用ClassManifestClassTag(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

你是指monoidal而不是monadic?另外,我非常确定'零'已经从scalaz-7中移除 - 你必须有一个'Monoid'实例。 – 2013-02-13 06:34:48

+0

@KristianDomagala我确实,对不起。是的,我听说'Zero'不再与'Monoid'分开,但是Scalaz 7还没有出来。 – 2013-02-13 06:54:49

0

正如丹尼尔说的那样,如果没有A的某些类型限制,通常是不可能的。有关更改方法取默认值,明示或暗示什么:

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

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