Last active
August 29, 2015 14:27
-
-
Save ubourdon/0b17f0b43a68c89b74e1 to your computer and use it in GitHub Desktop.
Why have this compilation error & how to fix it
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
/** In fact I try to write parametric Eventsourcing apply function | |
* And which allow me to have a parametric function for CommandHandler[D] too. | |
*/ | |
trait ApplyTo { | |
def applyTo[E, S](startingState: S)(events: List[E])(implicit de: DomainEvent.Aux[E, S]): S = { | |
events.foldLeft(startingState) { (currentState, event) => de.apply(currentState, event) } | |
} | |
} | |
@implicitNotFound("No member of type class DomainEvent found for type ${A}") | |
trait DomainEvent[A] { | |
type State | |
def apply(currentState: State, event: A): State | |
} | |
object DomainEvent { | |
//def apply[T: DomainEvent]: DomainEvent[T] = implicitly[DomainEvent[T]] | |
type Aux[A, S] = DomainEvent[A] { type State = S } | |
implicit object TicketEventTypeclass extends DomainEvent[TicketEvent] { | |
type State = TicketModel.State | |
override def apply(currentState: State, event: TicketEvent): State = ticket.models.apply(currentState, event) | |
} | |
} |
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
trait TicketCommandHandler extends ApplyTo { | |
type DomainEither[DomainError, State] = EitherT[Future, DomainError, State] | |
type NextState = TicketModel.Ticket | |
type TicketEither[A] = DomainEither[TicketError, A] // <: TicketModel.State | |
def CommandHandler(command: TicketCommand)(implicit eventReader: EventStream.Id => Future[List[TicketEvent]] = Eventstore.read[TicketEvent], | |
eventWriter: (EventStream.Id, List[TicketEvent]) => Future[WriteEventsCompleted] = Eventstore.write[TicketEvent]): TicketEither[TicketModel.State] = { | |
val streamId = ticketEventStreamId(command) | |
eventReader(streamId).map { events => applyTo(TicketModel.EmptyTicket: TicketModel.State)(events) } | |
.map { state => (state, decide(state, command)) } | |
.flatMap { case (state, decideResult) => | |
decideResult.traverse { events => | |
eventWriter(streamId, events).map { _ => applyTo(state)(events) } | |
} | |
} |> fEitherT | |
} | |
private def ticketEventStreamId(command: TicketCommand): EventStream.Id = EventStream.Id(s"ticket-${command.aggregateUid.safeValue}") | |
} | |
object TicketCommandHandler extends TicketCommandHandler |
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
object TicketModel { | |
sealed trait State | |
case object EmptyTicket extends State | |
case class Ticket(uid: SafeTicketUid, | |
agencyUid: SafeAgencyUid, | |
user: TicketUser, | |
operatorUid: SafeOperatorUid, | |
infos: TicketInfos, | |
openedDate: DateTime, | |
journal: List[OtherTicketEvent], | |
isClosed: Boolean = false) extends State | |
} |
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
trait GenericTrait { | |
def generic[A: TypeClass](x: TypeClass[A]#Result)(y: List[A]): TypeClass[A]#Result = | |
y.foldLeft(x) { (a, b) => TypeClass[A].aMethod(a, b) } | |
} | |
import scala.annotation.implicitNotFound | |
@implicitNotFound("No member of type class TypeClass found for type ${A}") | |
trait TypeClass[A] { | |
type Result | |
def aMethod(x: Result, y: A): Result | |
} | |
object TypeClass { | |
def apply[T: TypeClass]: TypeClass[T] = implicitly[TypeClass[T]] | |
implicit object InstanceTypeclass extends TypeClass[AnInstance] { | |
type Result = AResult | |
override def aMethod(x: Result, y: AnInstance): Result = ??? | |
} | |
} | |
case class AnInstance() | |
case class AResult() | |
/** | |
* [error] /../TypeClass.scala:3: type mismatch; | |
[error] found : a.type (with underlying type domain.service.TypeClass[A]#Result) | |
[error] required: _5.Result where val _5: domain.service.TypeClass[A] | |
[error] y.foldLeft(x) { (a, b) => TypeClass[A].aMethod(a, b) } | |
[error] ^ | |
[error] one error found | |
[error] (compile:compile) Compilation failed | |
* / |
No it's ok this compile. But I lost some message i post in gist.
Thx for your help.
Should events: List[E]
be an HList instead ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have to leave, i'll answer later...
that's the last part of the question... your code compiles but how do you use it... your type-dependent is a bit weird and you need to show some usage code to see what is the right way to write it ;)