Last active
February 7, 2019 22:39
-
-
Save fmonniot/8a0c826af8003bbd459e38624029744c to your computer and use it in GitHub Desktop.
Failing path dependent types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object test { | |
trait Entity { | |
type Id | |
type Attribute <: EntityAttribute | |
def attributes: NonEmptyList[Attribute] | |
} | |
trait EntityCompanion { | |
type Ret <: Entity | |
// Those three should be the type defined in Entity | |
type Id // previously type Id = Ret#Id | |
type Attribute <: EntityAttribute // type Attribute = Ret#Attribute | |
def apply(attributes: NonEmptyList[Attribute]): Ret | |
implicit val idMeta: doobie.Meta[Id] | |
implicit val attributeWrite: doobie.Write[Attribute] | |
} | |
trait EntityRepository { | |
def updateEntity[E <: EntityCompanion](e: E)(id: e.Id, entity: e.Ret): doobie.ConnectionIO[Unit] = { | |
statements.updateAttributes(e).updateMany { | |
entity.attributes.map { attribute: entity.Attribute => | |
// Fail here, as we get an `entity.Attiribute` and we wants an `e.Attribute` for the update | |
(attribute, id) | |
} | |
}.map(_ => ()) | |
} | |
object statements { | |
def updateAttributes[E <: EntityCompanion](e: E): doobie.Update[(e.Attribute, e.Id)] = { | |
import e.idMeta, e.attributeWrite | |
??? // Write the doobie query, using the implicit above | |
} | |
} | |
} | |
sealed trait EntityAttribute | |
// For the sake of simplicity, redefine libraries base construct here | |
final case class NonEmptyList[+A](head: A, tail: List[A]) { | |
def map[B](f: A => B): NonEmptyList[B] = NonEmptyList(f(head), tail.map(f)) | |
} | |
object doobie { | |
final class Meta[A](val get: Get[A], val put: Put[A]) | |
sealed abstract class Get[A] | |
sealed abstract class Put[A] | |
sealed abstract class Read[A] | |
sealed abstract class Write[A] | |
trait ConnectionIO[A] { | |
def map[B](f: A => B): ConnectionIO[B] | |
} | |
trait Update[A] { | |
def updateMany(fa: NonEmptyList[A]): ConnectionIO[Int] | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment