Created
March 26, 2018 18:35
-
-
Save yasuabe/c07e8077b816c3cf74c7b2ff3bc0540a to your computer and use it in GitHub Desktop.
analysis patterns knowledge level implemented in type level programming
This file contains hidden or 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
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