Guest User

Untitled

a guest
Jul 19th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.09 KB | None | 0 0
  1. import shapeless._
  2.  
  3. trait Consume[Src, Snk] {
  4. def consume(source: Src, sink: Snk): Unit
  5. }
  6.  
  7.  
  8. trait ConsumeGeneric2{
  9. implicit def allConsumeGeneric[Src <: Source, Snk <: Sink, SinkAll <: Coproduct](
  10. implicit
  11. gen: Generic.Aux[Snk, SinkAll],
  12. consume: AllConsume[Src, SinkAll]
  13. ): Consume[Src, Snk] =
  14. (src, snk) => consume.consume(src, gen.to(snk))
  15. }
  16.  
  17. trait ConsumeGeneric1 extends ConsumeGeneric2 {
  18. implicit def consumeAllGeneric[Src <: Source, Snk <: Sink, SrcAll <: Coproduct](
  19. implicit
  20. gen: Generic.Aux[Src, SrcAll],
  21. consume: ConsumeAll[SrcAll, Snk]
  22. ): Consume[Src, Snk] =
  23. (src, snk) => consume.consume(gen.to(src), snk)
  24.  
  25.  
  26. }
  27.  
  28. object Consume extends ConsumeGeneric1 {
  29. def apply[Src, Snk](implicit consume: Consume[Src, Snk]): Consume[Src, Snk] = consume
  30.  
  31. implicit def consumeDirect[Src <: Source, Snk <: Sink, O, I](implicit ev1: Src <:< Source.Aux[O], ev2: Snk <:< Sink.Aux[I], ev3: O => I): Consume[Src, Snk] =
  32. (src, snk) => (snk: Sink.Aux[I]).offer((src: Source.Aux[O]).produce())
  33. }
  34.  
  35. trait ConsumeAll[Srcs <: Coproduct, Snk] extends Consume[Srcs, Snk]
  36. object ConsumeAll {
  37. implicit def consumeCnil[Snk]: ConsumeAll[CNil, Snk] = (srcs, snk) => srcs.impossible
  38. implicit def consumeCons[Src <: Source, T <: Coproduct, Snk <: Sink](implicit head: Consume[Src, Snk], tail: ConsumeAll[T, Snk]): ConsumeAll[Src :+: T, Snk] = {
  39. case (Inl(h), snk) => head.consume(h, snk)
  40. case (Inr(t), snk) => tail.consume(t, snk)
  41. }
  42. }
  43. trait AllConsume[Srcs, Snk <: Coproduct] extends Consume[Srcs, Snk]
  44. object AllConsume{
  45. implicit def consumeCnil[Src]: AllConsume[Src, CNil] = (src, snks) => snks.impossible
  46. implicit def consumeCons[Src <: Source, Snk <: Sink, T <: Coproduct](implicit head: Consume[Src, Snk], tail: AllConsume[Src, T]): AllConsume[Src, Snk :+: T] = {
  47. case (src, Inl(h)) => head.consume(src, h)
  48. case (src, Inr(t)) => tail.consume(src, t)
  49. }
  50. }
  51.  
  52. //implicitly[Int <:< Int]
  53.  
  54. sealed trait Source {
  55. type Result
  56. def produce(): Result
  57. }
  58.  
  59. object Source {
  60. type Aux[A] = Source {type Result = A}
  61.  
  62. class IntSource extends Source {
  63. override type Result = Int
  64. override def produce() = 4
  65. }
  66.  
  67. class LongSource extends Source {
  68. override type Result = Long
  69. override def produce() = 8
  70. }
  71. }
  72.  
  73. sealed trait Sink {
  74. type Input
  75. def offer(result: Input): Unit
  76. }
  77.  
  78. implicit class SinkOps[Snk <: Sink](val snk: Snk) /* extends AnyVal */{
  79. def consume[Src <: Source](src: Src)(implicit consume: Consume[Src, Snk]): Unit = consume.consume(src, snk)
  80. }
  81.  
  82. object Sink {
  83. type Aux[R] = Sink {type Input = R}
  84.  
  85. class BigDecimalSink extends Sink {
  86. override type Input = BigDecimal
  87. override def offer(in: BigDecimal) = println(s"bigDecimal $in")
  88. }
  89.  
  90. class LongSink extends Sink {
  91. override type Input = Long
  92. override def offer(in: Input) = println(s"long $in")
  93. }
  94.  
  95. class BigIntSink extends Sink {
  96. override type Input = BigInt
  97. override def offer(in: BigInt) = println(s"bigInt $in")
  98. }
  99. }
  100.  
  101.  
  102. import Source._
  103. import Sink._
  104.  
  105.  
  106. for {
  107. src <- List[Source](new IntSource, new LongSource)
  108. snk <- List[Sink](new LongSink, new BigIntSink, new BigDecimalSink)
  109. } snk.consume(src)
Add Comment
Please, Sign In to add comment