Skip to content

Instantly share code, notes, and snippets.

@davidandrzej
Created December 4, 2018 17:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidandrzej/4b04ffab7e222f28282cc5944044df87 to your computer and use it in GitHub Desktop.
Save davidandrzej/4b04ffab7e222f28282cc5944044df87 to your computer and use it in GitHub Desktop.
Type-level encoding of privacy layer
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