Skip to content

Instantly share code, notes, and snippets.

@kubukoz
Forked from matfournier/gadthelp.scala
Last active February 6, 2021 01:03
Show Gist options
  • Select an option

  • Save kubukoz/de038ab7eb94c6179a5726ce1b911cf2 to your computer and use it in GitHub Desktop.

Select an option

Save kubukoz/de038ab7eb94c6179a5726ce1b911cf2 to your computer and use it in GitHub Desktop.

Revisions

  1. kubukoz revised this gist Feb 6, 2021. 1 changed file with 17 additions and 5 deletions.
    22 changes: 17 additions & 5 deletions gadthelp.scala
    Original file line number Diff line number Diff line change
    @@ -1,16 +1,28 @@

    trait AA

    trait AA1
    trait BB
    trait BB1

    trait HasScenarios[A, B] {
    def scenarios: Map[String, Scenario[A, B]]
    }

    sealed trait Scenario[A, B]

    object Scenario {
    // later pattern matching let's me do GADT stuff in pattern matches fine
    case object A extends Scenario[AA, AA1]
    case object B extends Scenario[BB, BB1]
    // but how to get into this domain from the outside is the problem...(this doesn't compile obviously)
    def from[A, B](s: String): Scenario[A, B] = s match {
    case "a" => A
    case "b" => B
    }

    def from[A, B](s: String)(implicit hasScenarios: HasScenarios[A, B]): Scenario[A, B] = hasScenarios
    .scenarios
    .getOrElse(s, ??? /* fail the parser here */ )

    }


    // later usage using the GADT in a pattern match
    object Generator {
    def from[A, B](scenario: Scenario[A, B]): Box[A, B] = scenario match {
  2. @matfournier matfournier revised this gist Feb 6, 2021. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion gadthelp.scala
    Original file line number Diff line number Diff line change
    @@ -48,5 +48,9 @@ def doThing[A : Codec, B: Codec](box: Box[A, B], ...) {
    but if I type the initial parsing as a existential type
    I get the issue
    could not find implicit Codec[Box[_$1,_$2]]]; ensure no imports are missing or manually define an instanc
    could not find implicit Codec[Box[_$1,_$2]]]; ensure no imports are missing
    but there are definitely codecs that can be derived for Box[AA, AA1] and Box[BB, BB1]
    it just is confused as I've lost the typing, even though I should be getting it back
    on the pattern match in the gadt to go from Scenario -> Box[A, B]
    */
  3. @matfournier matfournier revised this gist Feb 6, 2021. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion gadthelp.scala
    Original file line number Diff line number Diff line change
    @@ -35,6 +35,8 @@ for {
    scenario = Scenario.from(someString) // will be Either[Throwable, Scenario[_, _]].liftTo[IO] or whatever later
    generator = Generator.from(scenario)
    thing <- doThing(generator)
    ...
    } yield ...
    @@ -46,5 +48,5 @@ def doThing[A : Codec, B: Codec](box: Box[A, B], ...) {
    but if I type the initial parsing as a existential type
    I get the issue
    could not find implicit ...Box[_$1,_$2]]; ensure no imports are missing or manually define an instanc
    could not find implicit Codec[Box[_$1,_$2]]]; ensure no imports are missing or manually define an instanc
    */
  4. @matfournier matfournier revised this gist Feb 6, 2021. 1 changed file with 25 additions and 1 deletion.
    26 changes: 25 additions & 1 deletion gadthelp.scala
    Original file line number Diff line number Diff line change
    @@ -12,15 +12,39 @@ object Scenario {
    }

    // later usage using the GADT in a pattern match

    object Generator {
    def from[A, B](scenario: Scenario[A, B]): Box[A, B] = scenario match {
    case A => constantA // returns some Box[AA, AA1]
    case B => constantB // returns some Box[BB, BB1]
    }
    }

    // later later usage
    // relies on the answer of Box[A, B] to lookup implicits for A, B.
    // I can use an existential type to parse the string and return Scenario[_,_] later
    // but then I lose the fact it's AA, AA1 or BB, BB1 later
    // and a bunch of implicit lookups fail because it can't find implicits for
    // _$1, and _$2

    /*
    e.g. I have some
    for {
    .. some stuff
    scenario = Scenario.from(someString) // will be Either[Throwable, Scenario[_, _]].liftTo[IO] or whatever later
    generator = Generator.from(scenario)
    thing <- doThing(generator)
    where doThing is
    def doThing[A : Codec, B: Codec](box: Box[A, B], ...) {
    }
    but if I type the initial parsing as a existential type
    I get the issue
    could not find implicit ...Box[_$1,_$2]]; ensure no imports are missing or manually define an instanc
    */
  5. @matfournier matfournier revised this gist Feb 6, 2021. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions gadthelp.scala
    Original file line number Diff line number Diff line change
    @@ -8,10 +8,7 @@ object Scenario {
    case "a" => A
    case "b" => B
    }
    // I can use an existential type here and return Scenario[_,_] later
    // but then I lose the fact it's AA, AA1 or BB, BB1 later
    // and a bunch of implicit lookups fail because it can't find implicits for
    // _$1, and _$2

    }

    // later usage using the GADT in a pattern match
    @@ -23,4 +20,7 @@ object Scenario {

    // later later usage
    // relies on the answer of Box[A, B] to lookup implicits for A, B.

    // I can use an existential type to parse the string and return Scenario[_,_] later
    // but then I lose the fact it's AA, AA1 or BB, BB1 later
    // and a bunch of implicit lookups fail because it can't find implicits for
    // _$1, and _$2
  6. @matfournier matfournier created this gist Feb 6, 2021.
    26 changes: 26 additions & 0 deletions gadthelp.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    sealed trait Scenario[A, B]
    object Scenario {
    // later pattern matching let's me do GADT stuff in pattern matches fine
    case object A extends Scenario[AA, AA1]
    case object B extends Scenario[BB, BB1]
    // but how to get into this domain from the outside is the problem...(this doesn't compile obviously)
    def from[A, B](s: String): Scenario[A, B] = s match {
    case "a" => A
    case "b" => B
    }
    // I can use an existential type here and return Scenario[_,_] later
    // but then I lose the fact it's AA, AA1 or BB, BB1 later
    // and a bunch of implicit lookups fail because it can't find implicits for
    // _$1, and _$2
    }

    // later usage using the GADT in a pattern match

    def from[A, B](scenario: Scenario[A, B]): Box[A, B] = scenario match {
    case A => constantA // returns some Box[AA, AA1]
    case B => constantB // returns some Box[BB, BB1]
    }

    // later later usage
    // relies on the answer of Box[A, B] to lookup implicits for A, B.