2017-04-16 124 views
0

我发现了两种方式,我可以做一个无形的副产品模式匹配。我也用Google搜索这个问题,并发现thisCleanless方式做形状匹配上形状的产品

import shapeless._ 

object ShapelessEx3 extends App { 
    case class Red() 
    case class Green() 
    case class Blue() 
    type Colors = Red :+: Green :+: Blue :+: CNil 
    val blue = Coproduct[Colors](Blue()) 
    val green = Coproduct[Colors](Green()) 
    printColor1(blue) 
    printColor2(green) 

    def printColor1(c: Colors) : Unit = { 
     (c.select[Red], c.select[Green], c.select[Blue]) match { 
     case (Some(_), None, None) => println("Color is red") 
     case (None, Some(_), None) => println("Color is green") 
     case (None, None, Some(_)) => println("Color is blue") 
     case _ => println("unknown color") 
     } 
    } 
    def printColor2(c: Colors) : Unit = { 
     c match { 
     case Inl(Red()) => println("color is red") 
     case Inr(Inl(Green())) => println("color is green") 
     case Inr(Inr(Inl(Blue()))) => println("color is blue") 
     case _ => println("unknown color") 
     } 
    } 
} 

但两者的功能是一样case (None, Some(_), None)Inr(Inr(Inl(Blue())))非常嘈杂。我怎么能这么简单的模式匹配,如

c match { 
    case Red() => 
    case Green() => 
    case Blue() => 
} 

回答

4

你可以使用Poly1例如

import shapeless._ 
case class Red() 
case class Green() 
case class Blue() 
type Colors = Red :+: Green :+: Blue :+: CNil 
val blue = Coproduct[Colors](Blue()) 
val green = Coproduct[Colors](Green()) 

object printColor extends Poly1 { 
    implicit def caseRed = at[Red] {r=> println("red") ;r } 
    implicit def caseBlue = at[Blue]{b=> println("blue");b } 
    implicit def caseGreen= at[Green]{g =>println("green");g } 
}                
green map printColor 
blue map printColor