在我的理解中:List,Option是具有* - >形状的种类。 * scala中的那种是否与Haskell中的相同?
如果它们相同,则List [Int]和List [String]是两种不同的类型。
但是,以下代码会显示错误double definition
,其中显示have same type after erasure
def fun1(a:Option[String]):Option[String] = a
def fun1(a:Option[Integer]):Option[Integer] = a
def fun2(a:List[String]) = a(0) + a(1)
def fun2(a:List[Int]) = (a(0) + a(1)).toString
答案 0 :(得分:3)
这部分是Java遗留问题。泛型类型参数在运行时不存在。 List[Int]
只是List
。从理论上讲,可以在编译时选择正确的实现,但是反思 - 他们是一样的。
在Haskell中,您没有函数重载,您必须为函数指定不同的名称。无论如何,这是一个好习惯。实际上,即使使用Haskell类型类,也不能为[Int]
和[String]
提供不同的实现,而不启用危险的语言扩展(FlexibleInstances
)。
编辑:java示例:
package foo;
import java.util.List;
class Foo {
void foo(List<Double> arr) {}
void foo(List<String> arr) {}
}
失败并出现类似错误
foo.java:7: error: name clash: foo(List<String>) and foo(List<Double>) have the same erasure
void foo(List<String> arr) {}
^
1 error
使用 它会起作用: 然而,您可以使用 为什么 如果我们尝试与之前相同的示例输入,则会收到错误: 您也可以在Scala中使用类型类方法。由于它依赖于implicits,并且您可以显式指定隐式参数,因此该方法比Haskell更安全。 似乎 scalac 选择最具体的实例: 然而,即使FlexibleInstances
扩展名的{-# LANGUAGE FlexibleInstances #-}
class Foo a where
foo :: a -> String
instance Foo (Maybe String) where
foo = maybe "" id
instance Foo (Maybe Int) where
foo = maybe "" show
*Main> foo (Just "bar")
"bar"
FlexibleInstances
s:newtype
class Foo a where
foo :: a -> String
newtype MaybeString = MaybeString (Maybe String)
newtype MaybeInt = MaybeInt (Maybe Int)
instance Foo MaybeString where
foo (MaybeString ms) = maybe "" id ms
instance Foo MaybeInt where
foo (MaybeInt mi) = maybe "" show mi
*Main> foo (MaybeString (Just "bar"))
"bar"
FlexibleInstances
有危险?这是一个值得拥有StackOverflow线程的问题。简而言之:引入不可判定的情况非常容易,即编译器不知道要选择哪个实例:class Foo a where
foo :: a -> String
newtype MaybeString = MaybeString (Maybe String)
newtype MaybeInt = MaybeInt (Maybe Int)
instance Foo MaybeString where
foo (MaybeString ms) = maybe "" id ms
instance Foo MaybeInt where
foo (MaybeInt mi) = maybe "" show mi
Overlapping instances for Foo (Maybe [Char])
arising from a use of ‘foo’
Matching instances:
instance Foo (Maybe String) -- Defined at Example.hs:6:10
instance Show a => Foo (Maybe a) -- Defined at Example.hs:9:10
In the expression: foo (Just "bar")
In an equation for ‘it’: it = foo (Just "bar")
trait Foo[A] {
def foo(opt: Option[A]): String
}
implicit val fooString: Foo[String] = new Foo[String] {
def foo(opt: Option[String]): String = opt match {
case Some(value) => value + " is string"
case None => ""
}
}
implicit def fooA[A]: Foo[A] = new Foo[A] {
def foo(opt: Option[A]): String = opt match {
case Some(value) => value.toString
case None => ""
}
}
def foo[A](x: Option[A])(implicit fInstance: Foo[A]): String =
fInstance.foo(x)
scala> foo(Option("bar"))
res4: String = bar is string
scala> foo(Option(2))
res5: String = 2
fooA
,我们也可以强制 scalac 使用String
:scala> foo(Option("bar"))(fooA)
res6: String = bar