Skip to content

Instantly share code, notes, and snippets.

@bblfish
Created September 19, 2012 20:50
Show Gist options
  • Save bblfish/3752170 to your computer and use it in GitHub Desktop.
Save bblfish/3752170 to your computer and use it in GitHub Desktop.
Claim Monad for X509 Certificates - having trouble running map on it
import java.net.URI
import scalaz.concurrent.Promise
import scalaz._
import Scalaz._
import language.implicitConversions
import language.higherKinds
case class Cert(cn: String, pubKey: BigInt, webids: List[URI] )
trait RequestHeader {
type Certificates = Cert
def cert: Promise[Claim[_,Certificates]]
}
trait Level
object Truth extends Level
object PubKeyVerified extends Level
trait Claim[L <: Level, S] {
protected val statements: S
val level: L
// you might want a dedicated type for this verification functions
// apart from the simple `Function1`... because then your intent will
// become clear and you don't get any 'undesired' implicit values
def verify[L2 <: Level, S2](implicit verify: Verificator[L, S, L2, S2]): Claim[L2, S2] = {
verify(this)
}
}
trait Verificator[L<: Level,S,L2<:Level,S2] {
def apply(s: Claim[L,S]): Claim[L2,S2]
}
trait TrueClaim[S] extends Claim[Truth.type,S] {
def st: S = statements
}
object Claim {
implicit val level: Level = Truth
implicit def truth[S](s: Claim[Truth.type,S]) = s.flatMap(s => new TrueClaim[S] {
protected val statements = s
val level = Truth
}
)
implicit def ClaimMonad[L <: Level](implicit lvl: L): Monad[({type f[+a] = Claim[L, a]})#f] =
new Monad[({type f[+a] = Claim[L, a]})#f] {
def point[A](a: => A) = new Claim[L,A] {
protected val statements : A = a
val level: L = lvl
}
def bind[A, B](fa: Claim[L,A])(f: A => Claim[L,B]) = f(fa.statements)
}
implicit def truthClaimMonad = ClaimMonad(Truth)
// implicit def pubKeyVerifiedClaimMonad = ClaimMonad(PubKeyVerified)
implicit def unapplyClaim[TC[_[_]], A0 <: Level, B0](implicit TC0: TC[({type λ[α] = Claim[A0, α]})#λ]): Unapply[TC, Claim[A0, B0]] {
type M[X] = Claim[A0, X]
type A = B0
} = new Unapply[TC, Claim[A0, B0]] {
type M[X] = Claim[A0, X]
type A = B0
def TC = TC0
def apply(ma: Claim[A0, B0]) = ma
}
}
@larsrh
Copy link

larsrh commented Sep 19, 2012

  implicit def unapplyClaim[TC[_[_]], A0 <: Level, B0](implicit TC0: TC[({type λ[α] = Claim[A0, α]})#λ]): Unapply[TC, Claim[A0, B0]] {
    type M[X] = Claim[A0, X]
    type A = B0
  } = new Unapply[TC, Claim[A0, B0]] {
    type M[X] = Claim[A0, X]
    type A = B0
    def TC = TC0
    def apply(ma: Claim[A0, B0]) = ma
  }

@bblfish
Copy link
Author

bblfish commented Sep 19, 2012

ok. After adding that unnapplyClaim and uncommenting the implicit def truth... in the code I get

scala> ClaimMonad.point(Cert("Henry Story",BigInt(123456789),List(new java.net.URI("http://bblfish.net/#hjs"))))
<console>:14: error: not found: value ClaimMonad
              ClaimMonad.point(Cert("Henry Story",BigInt(123456789),List(new java.net.URI("http://bblfish.net/#hjs"))))
              ^

scala> import Claim._
import Claim._

scala> ClaimMonad.point(Cert("Henry Story",BigInt(123456789),List(new java.net.URI("http://bblfish.net/#hjs"))))
<console>:17: error: diverging implicit expansion for type L
starting with method unapplyClaim in object Claim
              ClaimMonad.point(Cert("Henry Story",BigInt(123456789),List(new java.net.URI("http://bblfish.net/#hjs"))))
              ^

scala> ClaimMonad(Truth).point(Cert("Henry Story",BigInt(123456789),List(new java.net.URI("http://bblfish.net/#hjs"))))
res2: Claim[Truth.type,Cert] = Claim$$anon$1$$anon$3@66706ec

scala> res2.map( s => s.cn )
res3: scalaz.Unapply[scalaz.Functor,Claim[Truth.type,Cert]]{type M[X] = Claim[Truth.type,X]; type A = Cert}#M[String] = Claim$$anon$1$$anon$3@5c480fa4

scala> res3.st
<console>:19: error: value st is not a member of scalaz.Unapply[scalaz.Functor,Claim[Truth.type,Cert]]{type M[X] = Claim[Truth.type,X]; type A = Cert}#M[String]
              res3.st

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment