Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created March 26, 2018 18:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yasuabe/c07e8077b816c3cf74c7b2ff3bc0540a to your computer and use it in GitHub Desktop.
Save yasuabe/c07e8077b816c3cf74c7b2ff3bc0540a to your computer and use it in GitHub Desktop.
analysis patterns knowledge level implemented in type level programming
import shapeless.ops.coproduct.{IsCCons, Selector, Unifier}
import shapeless.{:+:, CNil, Coproduct}
// Party Types -------------------------
sealed trait PartyType
sealed trait Region extends PartyType
sealed trait Division extends PartyType
sealed trait Doctor extends PartyType
sealed trait Team extends PartyType
sealed trait Patient extends PartyType
// Party -------------------------
case class Party[T <: PartyType]()
// Accountability -------------------------
trait Accountability[AT <: AccountabilityType, C <: PartyType, R <: PartyType] {
val commissioner: Party[C]
val responsible : Party[R]
}
// AccountabilityType -------------------------
trait AccountabilityType {
type Commissioners <: Coproduct
type Responsibles <: Coproduct
def instance[C <: PartyType, R <: PartyType](
aCommissioner: Party[C],
aResponsible: Party[R]
)(implicit
sc: Selector[Commissioners, C],
sr: Selector[Responsibles, R]
): Accountability[this.type, C, R] =
new Accountability[this.type, C, R] {
val commissioner: Party[C] = aCommissioner
val responsible: Party[R] = aResponsible
}
}
object AccountabilityType {
def apply[C <: Coproduct, R <: Coproduct] = new {
def apply[PC <: PartyType, PR <: PartyType]()(
implicit consC: IsCCons[C],
consR: IsCCons[R],
unifierC: Unifier.Aux[C, PC],
unifierR: Unifier.Aux[R, PR]
) = new AccountabilityType {
type Commissioners = C
type Responsibles = R
}
}
}
// sample ----------------------------------------------------
val johnSmith = Party[Patient]()
val renalUnitTeam = Party[Team]()
val markThursz = Party[Doctor]()
val bostonRegion = Party[Region]()
val cappuccinoDivision = Party[Division]()
val regionStructureType = AccountabilityType [
Region :+: CNil,
Division :+: CNil
]()
val patientConsentType = AccountabilityType [
Patient :+: CNil,
Doctor :+: Team :+: CNil
]()
//val ngType1 = AccountabilityType [CNil, Division :+: CNil]()
//val ngType2 = AccountabilityType [Region :+: CNil, String :+: CNil]()
val pc1 = patientConsentType.instance(johnSmith, markThursz)
val pc2 = patientConsentType.instance(johnSmith, renalUnitTeam)
type PatientConsentType = patientConsentType.type
val pc3: Accountability[PatientConsentType, Patient, Doctor] = pc1
val rs = regionStructureType.instance(bostonRegion, cappuccinoDivision)
// val ng1 = patientConsentType.instance(johnSmith, Party[Patient])
// val ng2 = regionStructureType.instance(Party[Division], Party[Region])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment