如何实现返回递归匹配类型的递归Scala 3函数?
我无法实现返回递归匹配类型的函数。例如,我从std lib中取了元组附加
类型,并尝试实现一个简单的附加
函数。
// Tuple append match type, copied from std lib
type Append[X <: Tuple, Y] <: Tuple = X match {
case EmptyTuple => Y *: EmptyTuple
case x *: xs => x *: Append[xs, Y]
}
// Types work just fine
val x: Append[(String, Int), Long] = ("", 1, 2L)
// My simple function implementation that does not compile
def append[X <: Tuple, Y](x: X, y: Y): Append[X, Y] = x match
case _: EmptyTuple => y *: EmptyTuple
case x *: xs => x *: append(xs, y)
[E007] Type Mismatch Error:
case _: EmptyTuple => y *: EmptyTuple
^^^^^^^^^^^^^^^
Found: Y *: EmptyTuple.type
Required: Append[X, Y]
where: X is a type in method append with bounds <: Tuple
Note: a match type could not be fully reduced:
trying to reduce Append[X, Y]
failed since selector X
does not match case EmptyTuple => Y *: EmptyTuple
and cannot be shown to be disjoint from it either.
Therefore, reduction cannot advance to the remaining case
case x *: xs => x *: Append[xs, Y]
longer explanation available when compiling with `-explain`
[E007] Type Mismatch Error:
case x *: xs => x *: append(xs, y)
^^^^^^^^^^^^^^^^^^
Found: Any *: Append[Tuple, Y]
Required: Append[X, Y]
where: X is a type in method append with bounds <: Tuple
Note: a match type could not be fully reduced:
trying to reduce Append[Tuple, Y]
failed since selector Tuple
does not match case EmptyTuple => Y *: EmptyTuple
and cannot be shown to be disjoint from it either.
Therefore, reduction cannot advance to the remaining case
case x *: xs => x *: Append[xs, Y]
longer explanation available when compiling with `-explain`
I fail to implement a function that returns a recursive match type. As an example, I took the tuple Append
type from the std lib and tried to implement a simple append
function.
// Tuple append match type, copied from std lib
type Append[X <: Tuple, Y] <: Tuple = X match {
case EmptyTuple => Y *: EmptyTuple
case x *: xs => x *: Append[xs, Y]
}
// Types work just fine
val x: Append[(String, Int), Long] = ("", 1, 2L)
// My simple function implementation that does not compile
def append[X <: Tuple, Y](x: X, y: Y): Append[X, Y] = x match
case _: EmptyTuple => y *: EmptyTuple
case x *: xs => x *: append(xs, y)
[E007] Type Mismatch Error:
case _: EmptyTuple => y *: EmptyTuple
^^^^^^^^^^^^^^^
Found: Y *: EmptyTuple.type
Required: Append[X, Y]
where: X is a type in method append with bounds <: Tuple
Note: a match type could not be fully reduced:
trying to reduce Append[X, Y]
failed since selector X
does not match case EmptyTuple => Y *: EmptyTuple
and cannot be shown to be disjoint from it either.
Therefore, reduction cannot advance to the remaining case
case x *: xs => x *: Append[xs, Y]
longer explanation available when compiling with `-explain`
[E007] Type Mismatch Error:
case x *: xs => x *: append(xs, y)
^^^^^^^^^^^^^^^^^^
Found: Any *: Append[Tuple, Y]
Required: Append[X, Y]
where: X is a type in method append with bounds <: Tuple
Note: a match type could not be fully reduced:
trying to reduce Append[Tuple, Y]
failed since selector Tuple
does not match case EmptyTuple => Y *: EmptyTuple
and cannot be shown to be disjoint from it either.
Therefore, reduction cannot advance to the remaining case
case x *: xs => x *: Append[xs, Y]
longer explanation available when compiling with `-explain`
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在返回比赛类型方面,编译器非常挑剔。您的第二种情况需要进行少量修改以使其在没有演员的情况下工作( scastie )
:
:(x *:xs)
,编译器不明白您的函数的第二种情况与匹配类型的第二种情况相对应。也许将来会更聪明。The compiler is very fussy when it comes to returning match types. Your second case needs a small modification to get it to work without the cast (Scastie):
Without the
: (x *: xs)
, the compiler doesn't understand that your function's second case corresponds with the second case of the match type. Perhaps in the future it'll be smarter.附加
函数中的铸件可以做到这一点。我无法内联
它,但这暂时就足够了。scastie
A cast in the
append
function did the trick. I couldn't manage toinline
it, but this is sufficient for now.Scastie