Scala 如何在dotty中编写带有窄字符串类型元组头大小写的匹配类型模式?
我目前正在尝试了解Scala 3/dotty的新特性。所以我试图重做一些我以前用Shapess试过的东西。给定一个窄字符串类型的异构列表(在shapeless中是Scala 如何在dotty中编写带有窄字符串类型元组头大小写的匹配类型模式?,scala,types,pattern-matching,dotty,scala-3,Scala,Types,Pattern Matching,Dotty,Scala 3,我目前正在尝试了解Scala 3/dotty的新特性。所以我试图重做一些我以前用Shapess试过的东西。给定一个窄字符串类型的异构列表(在shapeless中是“a”:“c”:“f”::HNil,在dotty中,据我所知,元组可以被使用(“a”,“c”,“f”)),我想根据一些映射替换这些类型。例如,考虑伪代码: MyListOfNames=(“a”、“c”、“f”)类型 类型映射=(“a”->“b”,“c”->“d”) //以某种方式将映射/替换应用为新类型别名“MyListOfRename
“a”:“c”:“f”::HNil
,在dotty中,据我所知,元组可以被使用(“a”,“c”,“f”)
),我想根据一些映射替换这些类型。例如,考虑伪代码:
MyListOfNames=(“a”、“c”、“f”)类型
类型映射=(“a”->“b”,“c”->“d”)
//以某种方式将映射/替换应用为新类型别名“MyListOfRenamedNames”`
类型MyListOfRenamedNames=(“b”、“d”、“f”)
为此,我提出了以下代码。重新映射单个缩小的字符串类型正在工作。但我无法让它与元组一起工作:
对象A:
性状重映射
case对象空扩展重映射
案例类侦察[N1尝试引入助手类型并将其用作类型模式
type Hlp[X <: String, Rest <: Tuple] = X *: Rest
type AllRemapped[T <: Tuple, R <: Remapping] <: Tuple = T match {
case Unit => Unit
case Hlp[s, rest] => Remapped[s, R] *: AllRemapped[rest, R]
}
使用inline
可以
inline def g(x: "a" | "c" | "f") <: String = inline x match {
case "a" => "b"
case "c" => "d"
case "f" => "f"
}
g("a"): "b"
g("c"): "d"
g("f"): "f"
// g("x") // doesn't compile
内联定义g(x:“a”|“c”|“f”)“b”
案例“c”=>“d”
案例“f”=>案例“f”
}
g(“a”):“b”
g(“c”):“d”
g(“f”):“f”
//g(“x”)//不编译
试一试
重新映射
case对象空扩展重映射
case class ReCons[N1感谢您的回答@Dymtro Mitin,我还没有尝试添加中间类型别名。这起作用:+1:。通过内联和擦除,我指的是一个解决方案,它仍然没有运行时占用空间,但实现了类似的效果(例如,调用内联函数以替换元组版本)。我相信这也是可以做到的。我注意到您使用lamba和Tuple.Map进行编辑,这很酷,谢谢。@ciuncan对我来说,这不是编译。..=inline r match{…
失败于无法减少与scrutinee的内联匹配
。我必须将此更改为inline def getremap[N getremap(N,rc.rest);case ReCons(u,u,ReEmpty)=>n}
@ciuncan可能专门的内联def目前在类型级别@ciuncan上工作不太好,在我意识到如何对hlists的串联进行编码后,我还修复了您的代码。请参阅更新。类型Concat[Xs
inline def g(x: "a" | "c" | "f") <: String = inline x match {
case "a" => "b"
case "c" => "d"
case "f" => "f"
}
g("a"): "b"
g("c"): "d"
g("f"): "f"
// g("x") // doesn't compile
sealed trait Remapping
case object ReEmpty extends Remapping
case class ReCons[N1 <: String, N2 <: String, R <: Remapping](n1: N1, n2: N2, rest: R) extends Remapping
type Remapped[X <: String, R <: Remapping] <: String = R match {
case ReEmpty.type => X
case ReCons[X, n, _] => n
case ReCons[_, _, rr] => Remapped[X, rr]
}
inline def getRemapped[X <: String & Singleton, R <: Remapping] erased (x: X, r: R) <: String = inline r match {
case ReEmpty => x
case rc: ReCons[X, _, _] => rc.n2
case rc: ReCons[_, _, _] => getRemapped(x, rc.rest).asInstanceOf[Remapped[X, R]]
}
type RemapAtoBAndCtoD = ReCons["a", "b", ReCons["c", "d", ReEmpty.type]]
val remapping: RemapAtoBAndCtoD = ReCons("a", "b", ReCons("c", "d", ReEmpty))
val remapped2: ("b", "d", "f") = (
getRemapped("a", remapping),
getRemapped("c", remapping),
getRemapped("f", remapping)
) // (b,d,f)
//myList.map[[X <: String] =>> Remapped[X, RemapAtoBAndCtoD]]([X <: String] => (x: X) => getRemapped(x, remapping))
//[error] |Found: Object with PolyFunction {...}
//[error] |Required: PolyFunction{apply: [t](x$1: t): A.Remapped[t, A.RemapAtoBAndCtoD]}
//https://github.com/milessabin/shapeless/pull/901