Skip to content

Instantly share code, notes, and snippets.

@davidandrzej
Created December 3, 2018 23:00
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save davidandrzej/487d84e52acd1ce970fa783b56b1fd94 to your computer and use it in GitHub Desktop.
Value-encoding of privacy layer
import scala.annotation.tailrec
import scala.language.higherKinds
object ValPrivacy {
sealed trait PrivacyLevel
case object High extends PrivacyLevel
case object Neutral extends PrivacyLevel
case object Low extends PrivacyLevel
def high[T](data: T): ValSec[T] = new ValSec(High, data)
def low[T](data: T): ValSec[T] = new ValSec(Low, data)
def point[T](data: T): ValSec[T] = new ValSec(Neutral, data)
class ValSec[T](level: PrivacyLevel, data: T) {
val _level = level
protected val _data = data
def ffmap[S](f: T => S): ValSec[S] = new ValSec(level, f(_data))
def bind[S](f: T => ValSec[S]): ValSec[S] = {
val result = f(_data)
(this._level, result._level) match {
case (x, Neutral) => new ValSec(x, result._data)
case _ => result
}
}
def reveal: Option[T] = level match {
case High => None
case Neutral | Low => Some(_data)
}
def tailRecHelper[B](f: T => ValPrivacy.ValSec[Either[T, B]]): ValPrivacy.ValSec[B] = {
this.tailRecM(this._data)(f)
}
@tailrec
final def tailRecM[A, B](a: A)(f: A => ValPrivacy.ValSec[Either[A, B]]): ValPrivacy.ValSec[B] = {
val result = f(a)
result._data match {
case Left(aa) => tailRecM(aa)(f)
case Right(bb) => new ValSec(result._level, bb)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment