返回带有类型类但没有其他类型信息的类型



假设我有一些类型类:

trait Greeter[A] {
def greet(a: A): String
}

我想编写一个返回存在此类型类实例的值的方法:

implicit val intGreeter = new Greeter[Int] {
def greet(n: Int): String = s"Hello, integer $n!"
}
implicit val doubleGreeter = new Greeter[Double] {
def greet(d: Double): String = s"Hello, double $d"
}
def foo(b: Boolean): <X> = {
if (b) 3 else 1.0
}

其中<X>是某种类型签名。然后像这样使用它:

val g: <X> = foo(true)
println(implicitly[Greeter[<X>]].greet(g))

当然,这并不直接起作用。我可以做这样的事情:

trait Greetable {
def greet: String
}
def getGreetable[A : Greeter](a: A) = new Greetable {
def greet: String = implicitly[Greeter[A]].greet(a)
}
def foo(b: Boolean): Greetable = {
if (b) getGreetable(3) else getGreetable(1.0)
}

这工作得很好,但它似乎有点不方便,而且不是真正的可扩展性。我必须为每个类型类定义相应的特征。如果我想要一个包含两个类型类实例的返回类型怎么办?还是n?这也感觉像是一种非常OO的方法;FP世界中是否有解决此问题的内容?

只要您的方法确实需要根据某些条件返回 3 或 1.0,并且该部分无法更改,那么您肯定需要返回类型的 sum 类型。

这可以通过一个公共超类(这是您采用的方法(或通过不相交的并集(例如Eitherscalaz./等(进行建模,在这种情况下,您将返回例如Int / Double.如果可能出现许多潜在的类型,那么您将需要"其中之一"或(更方便的(无形HList,或者干脆坚持超类Greetable

我认为这种情况的笨拙不是源于解决方案,而是源于问题本身。基于某些内部逻辑返回两种或多种不同类型的方法并不是真正的FP本身,是吗?:)

相关内容

  • 没有找到相关文章

最新更新