我有scala泛型的问题.虽然我在这里定义的第一个函数似乎完全可以,但编译器抱怨第二个定义:
error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
def >>[B](a: C[B])(implicit m: Monad[C]): C[B] = {
^
Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?
trait Lifter[C[_]] {
implicit def liftToMonad[A](c: C[A]) = new {
def >>=[B](f: A => C[B])(implicit m: Monad[C]): C[B] = {
m >>= (c, f)
}
def >>[B](a: C[B])(implicit m: Monad[C]): C[B] = {
m >> a
}
}
}
Run Code Online (Sandbox Code Playgroud)
重要提示:这不是关于Monads的问题,这是一个关于scala多态性的问题.
编辑:这是我的Monad定义
trait Monad[C[_]] {
def >>=[A, B](a: C[A], f: A => C[B]): …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个处理Fibonacci序列的泛型迭代器:
def FibIter[T](fst:T , snd:T)(implicit num:Numeric[T]) = new Iterator[T] {
var fn1 = fst
var fn2 = snd
def hasNext = true
def next() = {
val ret = fn1
fn1 = fn2
fn2 = num.plus(ret,fn2)
ret
}
}
Run Code Online (Sandbox Code Playgroud)
但是,编译器抱怨前两个变量赋值:
结构细化中的参数类型可能不是指在该细化之外定义的抽象类型
有谁知道如何解决这个问题?非常感谢你!
我想要一个名为"double"的泛型函数,其行为与此类似,可以应用于任何类型的def +(x:T):T方法:
double("A")
> "AA"
double(1)
> 2
double(0.2)
> 0.4
Run Code Online (Sandbox Code Playgroud)
所以我写这个函数是这样的:
def double[T](x:T):T = { x+x }
Run Code Online (Sandbox Code Playgroud)
但是当我在REPL中运行它时,scala会对此进行评估:
scala> def double[T](x:T):T = { x+x }
<console>:7: error: type mismatch;
found : T
required: String
def double[T](x:T):T = { x+x }
^
Run Code Online (Sandbox Code Playgroud)
我认为结构类型可能是实现duck typing的一种方法,我尝试过这样的东西,但它也不起作用:
def double[T <: { def +(x:T):T }](x:T):T = { x + x }
def double[T <: { def +[U<:T](x:U):U}](x:T) = { x + x }
Run Code Online (Sandbox Code Playgroud)
有没有人有这个想法?谢谢!
我发现在Haskell中,类似的函数可以像这样写:
double x = x + …Run Code Online (Sandbox Code Playgroud) generics functional-programming scala type-inference duck-typing