-
-
Save davidandrzej/4b04ffab7e222f28282cc5944044df87 to your computer and use it in GitHub Desktop.
Type-level encoding of privacy layer
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
import scala.language.higherKinds | |
object Privacy { | |
sealed trait PrivacyLevel { type Outer[X <: PrivacyLevel] <: PrivacyLevel } | |
sealed trait Revealable extends PrivacyLevel | |
object High extends PrivacyLevel { type Outer[X] = High.type } | |
type High = High.type | |
object Neutral extends PrivacyLevel with Revealable { type Outer[X <: PrivacyLevel] = X } | |
type Neutral = Neutral.type | |
object Low extends PrivacyLevel with Revealable { type Outer[X] = Low.type } | |
type Low = Low.type | |
object Sec { | |
def apply[PL <: PrivacyLevel, T](data: T): Sec[PL, T] = { | |
new Sec(data) | |
} | |
def point[T](data: T): Privacy.Sec[Neutral, T] = apply(data) | |
def high[T](data: T): Privacy.Sec[High, T] = apply(data) | |
def low[T](data: T): Privacy.Sec[Low, T] = apply(data) | |
def join[T, PLO <: PrivacyLevel, PLI <: PrivacyLevel] | |
(x: Sec[PLO, Sec[PLI, T]]) | |
: Sec[PLI#Outer[PLO], T] = { | |
Sec.apply[PLI#Outer[PLO], T](x._data._data) | |
} | |
def reveal[T, PL <: Revealable](secret: Sec[PL, T]): T = { | |
secret._data | |
} | |
} | |
class Sec[PL <: PrivacyLevel, T](data: T) { | |
protected val _data = data | |
def map[S](f: T => S): Sec[PL, S] = Sec[PL, S](f(_data)) | |
def flatMap[S, NN <: PrivacyLevel](f: T => Sec[NN, S]): Sec[NN#Outer[PL], S] = | |
Sec.join(this.map(f)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment