Created
September 19, 2012 20:50
-
-
Save bblfish/3752170 to your computer and use it in GitHub Desktop.
Claim Monad for X509 Certificates - having trouble running map on it
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 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 | |
} | |
} |
here with the implict for level fixed
> console
[info] Starting scala interpreter...
[info]
import scalaz._
import Scalaz._
Welcome to Scala version 2.10.0-M7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_35).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import Claim._
import Claim._
scala> implicit val level: Truth.type = Truth
level: Truth.type = Truth$@76d5a295
scala> implicitly[Truth.type]
res0: Truth.type = Truth$@76d5a295
scala> ClaimMonad(Truth).point(Cert("Henry Story",BigInt(123456789),List(new java.net.URI("http://bblfish.net/#hjs"))))
res1: Claim[Truth.type,Cert] = Claim$$anon$1$$anon$2@785b02ed
scala> res1.map( s: Cert => s.cn )
<console>:19: error: Unable to unapply type `Claim[Truth.type,Cert]` into a type constructor of kind `M[_]` that is classified by the type class `scalaz.Functor`
1) Check that the type class is defined by compiling `implicitly[scalaz.Functor[<type constructor>]]`.
2) Review the implicits in object Unapply, which only cover common type 'shapes'
(implicit not found: scalaz.Unapply[scalaz.Functor, Claim[Truth.type,Cert]])
res1.map( s: Cert => s.cn )
With the implicit val level: Truth.type = Truth
should ClaimMonad.point
not be enough ( no need for ClaimMonad(Truth).point
)
Perhaps the problem is with the following
scala> ClaimMonad.point(Cert("Henry Story",BigInt(123456789),List(new java.net.URI("http://bblfish.net/#hjs"))))
<console>:18: error: diverging implicit expansion for type L
starting with method ClaimMonad in object Claim
ClaimMonad.point(Cert("Henry Story",BigInt(123456789),List(new java.net.URI("http://bblfish.net/#hjs"))))
the build.sbt was placed in the hime directory
scalaVersion := "2.10.0-M7"
resolvers += "Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/snapshots/"
libraryDependencies ++= Seq(
"org.scalaz" % "scalaz-core" % "7.0.0-M3" cross CrossVersion.full
)
scalacOptions += "-feature"
initialCommands in console := "import scalaz._, Scalaz._"
initialCommands in console in Test := "import scalaz._, Scalaz._, scalacheck.ScalazProperties._, scalacheck.ScalazArbitrary._,scalacheck.ScalaCheckBinding._"
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
}
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
Here's what happens in the scala console