debasishg / frdomain Goto Github PK
View Code? Open in Web Editor NEWCode repo for Functional and Reactive Domain Modeling
License: Apache License 2.0
Code repo for Functional and Reactive Domain Modeling
License: Apache License 2.0
Hi,
I'm unable to successfully import the project as an sbt project in IntelliJ IDEA 2019.3.
Are others able to import and build OK?
The import output is as follows:
Error while importing sbt project:
List([info] Loading global plugins from /Users/bayo/.sbt/0.13/plugins
[info] Loading project definition from /Users/bayo/dev/frdomain/project
Missing bintray credentials /Users/bayo/.bintray/.credentials. Some bintray features depend on this.
[info] Set current project to frdomain (in build file:/Users/bayo/dev/frdomain/)
>
[info] Defining */*:sbtStructureOptions, */*:sbtStructureOutputFile and 1 others.
[info] The new values will be used by *:cleanKeepFiles
[info] Run `last` for details.
[info] Reapplying settings...
Missing bintray credentials /Users/bayo/.bintray/.credentials. Some bintray features depend on this.
[info] Set current project to frdomain (in build file:/Users/bayo/dev/frdomain/)
[info] Applying State transformations org.jetbrains.sbt.CreateTasks from /Users/bayo/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-1/193.5233.102/IntelliJ IDEA 2019.3 EAP.app.plugins/Scala/repo/org.jetbrains/sbt-structure-extractor/scala_2.10/sbt_0.13/2018.2.1+4-88400d3f/jars/sbt-structure-extractor.jar
[info] Reapplying settings...
Missing bintray credentials /Users/bayo/.bintray/.credentials. Some bintray features depend on this.
[info] Set current project to frdomain (in build file:/Users/bayo/dev/frdomain/)
[warn] Credentials file /Users/bayo/.bintray/.credentials does not exist
[info] Updating {file:/Users/bayo/dev/frdomain/}root...
[info] Resolving org.scala-lang#scala-library;2.11.8 ...
[info] Resolving org.scalaz#scalaz-core_2.11;7.2.4 ...
[info] Resolving org.scalaz#scalaz-concurrent_2.11;7.2.4 ...
[info] Resolving org.scalaz#scalaz-effect_2.11;7.2.4 ...
[info] Resolving joda-time#joda-time;2.9.1 ...
[info] Resolving org.joda#joda-convert;1.8.1 ...
[info] Resolving io.spray#spray-json_2.11;1.3.2 ...
[info] Resolving com.typesafe.akka#akka-actor_2.11;2.4.8 ...
[info] Resolving com.typesafe#config;1.3.0 ...
[info] Resolving org.scala-lang.modules#scala-java8-compat_2.11;0.7.0 ...
[info] Resolving com.typesafe.akka#akka-persistence_2.11;2.4.8 ...
[info] Resolving com.typesafe.akka#akka-protobuf_2.11;2.4.8 ...
[info] Resolving com.typesafe.akka#akka-stream_2.11;2.4.8 ...
[info] Resolving com.typesafe#ssl-config-akka_2.11;0.2.1 ...
[info] Resolving com.typesafe#ssl-config-core_2.11;0.2.1 ...
[info] Resolving org.scala-lang.modules#scala-parser-combinators_2.11;1.0.4 ...
[info] Resolving org.reactivestreams#reactive-streams;1.0.0 ...
[info] Resolving com.typesafe.scala-logging#scala-logging-slf4j_2.11;2.1.2 ...
[info] Resolving com.typesafe.scala-logging#scala-logging-api_2.11;2.1.2 ...
[info] Resolving org.scala-lang#scala-reflect;2.11.0 ...
[info] Resolving org.slf4j#slf4j-api;1.7.7 ...
[info] Resolving com.typesafe.slick#slick_2.11;3.0.0 ...
[info] Resolving com.h2database#h2;1.4.187 ...
[info] Resolving com.zaxxer#HikariCP-java6;2.3.8 ...
[info] Resolving com.zaxxer#HikariCP-java6;2.3.8 ...
[info] Resolving com.zaxxer#HikariCP-parent;2.3.8 ...
[info] Resolving com.zaxxer#HikariCP-parent;2.3.8 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving com.zaxxer#HikariCP-parent;2.3.8 ...
[info] Resolving com.zaxxer#HikariCP-parent;2.3.8 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving ch.qos.logback#logback-classic;1.1.3 ...
[info] Resolving ch.qos.logback#logback-core;1.1.3 ...
[info] Resolving org.scalacheck#scalacheck_2.11;1.12.5 ...
[info] Resolving org.scala-sbt#test-interface;1.0 ...
[info] Resolving com.milessabin#si2712fix-plugin_2.11.8;1.2.0 ...
[info] Resolving org.spire-math#kind-projector_2.11;0.8.0 ...
[info] Resolving org.scala-lang#scala-compiler;2.11.7 ...
[info] Resolving org.scala-lang#scala-reflect;2.11.7 ...
[info] Resolving org.scala-lang.modules#scala-xml_2.11;1.0.4 ...
[info] Resolving org.scala-lang#scala-compiler;2.11.8 ...
[info] Resolving org.scala-lang#scala-reflect;2.11.8 ...
[info] Resolving jline#jline;2.12.1 ...
[info] Resolving jline#jline;2.12.1 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[info] Resolving org.sonatype.oss#oss-parent;7 ...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.zaxxer#HikariCP-java6;2.3.8: several problems occurred while resolving dependency: com.zaxxer#HikariCP-java6;2.3.8 {compile=[default(compile)]}:
[warn] several problems occurred while resolving dependency: com.zaxxer#HikariCP-parent;2.3.8 {}:
[warn] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn]
[warn] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn]
[warn]
[warn] several problems occurred while resolving dependency: com.zaxxer#HikariCP-parent;2.3.8 {}:
[warn] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn]
[warn] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] :: jline#jline;2.12.1: several problems occurred while resolving dependency: jline#jline;2.12.1 {optional=[compile(*), master(compile)]}:
[warn] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn]
[warn] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] Note: Unresolved dependencies path:
[warn] com.zaxxer:HikariCP-java6:2.3.8 (/Users/bayo/dev/frdomain/build.sbt#L13)
[warn] +- frdomain:frdomain_2.11:0.0.1
[warn] jline:jline:2.12.1
[warn] +- org.scala-lang:scala-compiler:2.11.8
[warn] +- frdomain:frdomain_2.11:0.0.1
[trace] Stack trace suppressed: run 'last *:ssExtractDependencies' for the full output.
[trace] Stack trace suppressed: run 'last *:update' for the full output.
[error] (*:ssExtractDependencies) sbt.ResolveException: unresolved dependency: com.zaxxer#HikariCP-java6;2.3.8: several problems occurred while resolving dependency: com.zaxxer#HikariCP-java6;2.3.8 {compile=[default(compile)]}:
[error] several problems occurred while resolving dependency: com.zaxxer#HikariCP-parent;2.3.8 {}:
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error]
[error] several problems occurred while resolving dependency: com.zaxxer#HikariCP-parent;2.3.8 {}:
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error]
[error]
[error] unresolved dependency: jline#jline;2.12.1: several problems occurred while resolving dependency: jline#jline;2.12.1 {optional=[compile(*), master(compile)]}:
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] (*:update) sbt.ResolveException: unresolved dependency: com.zaxxer#HikariCP-java6;2.3.8: several problems occurred while resolving dependency: com.zaxxer#HikariCP-java6;2.3.8 {compile=[default(compile)]}:
[error] several problems occurred while resolving dependency: com.zaxxer#HikariCP-parent;2.3.8 {}:
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error]
[error] several problems occurred while resolving dependency: com.zaxxer#HikariCP-parent;2.3.8 {}:
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error]
[error]
[error] unresolved dependency: jline#jline;2.12.1: several problems occurred while resolving dependency: jline#jline;2.12.1 {optional=[compile(*), master(compile)]}:
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss
#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error]
[error] several problems occurred while resolving dependency: org.sonatype.oss#oss-parent;7 {}:
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] org.sonatype.oss#oss-parent;7!oss-parent.pom(pom.original) origin location must be absolute: file:/Users/bayo/.m2/repository/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
[error] Total time: 13 s, completed Dec 6, 2019 8:13:08 PM)
The success code of "Open" method should be:
Success(Account(no,name,Some(openingDate.getOrElse(today)))The if-clause of "Close" method should be:
if (cd before account.dateOfOpen.get)
https://forums.manning.com/posts/list/36349.page#p101487 .. Maybe explain the diff between subtyping and parametric polymorphism from Scala point of view.
suggested in RR
The root cause why the operation need to return Future
is because repository. Rather than eagerly calling Future.apply
in service level, why can't we introduce Future
as the return type from repository, and compose it accordingly in service level?
Let's say our repository is non-blocking, we will call this already well-shaped repository in another thread, which is unnecessary.
Given the implicit context (which is my own guess), it seems like the code for nameLens
should probably be as follows:
protected val nameLens = Lens[Customer, String](
get = _.name,
set = (o, v) => o.copy(name = v)
)
Hi, is there an answer provided for exercise 4.1? i.e. what the pros and cons are of apply3
vs lift3
?
It looks like only solutions for 4.2 and 4.3 are provided.
Thanks
@debasishg a question about what comes first, Command
or Event
.
In the current code the service operations are mapped to a single Event
which, in turn is mapped to a Command
.
Seems this would not support a functionality where a service operation (logically a Command
) would need to generate multiple Event
s to different Aggregate
s.
Scenario: funds transfer would update Account
balances and update Customer
net worth.
Then there is the question of whether the Interpreter
is per Aggregate
or can work with more than one.
Please advise.
Hello @debasishg
Would you be open to adding exercise comments on the solutions?
For example, for Exercise 4.2, I would add that comment over here
https://github.com/debasishg/frdomain/blob/master/src/main/scala/frdomain/ch4/patterns/Account.scala#L46
I can do this if you like but it will take a while since I'm only on chapter 4 ๐
Currently making my way through the book in detail (awesome btw), and I realised that in Chapter 5, AccountService
is parameterised on Account
, Amount
, and Balance
, which is awesome, but AccountRepository
on which it depends is not; I was curious if it should be ?
In effect, doesn't this mean that AccountService
is coupled to the concrete models due to
?
as suggested in RR
"Consider the example from section 2.2.6 " should refer to section 3.3.6.
The code snippet should not extend AccountService and instead do an import AccountService._
Hello there,
I'm trying to implement the solution for Exercise 5.1. I managed to do it for the mutable state interpreter but I cannot seem to get it to work for the State interpreter even though I've aligned the types
The following mutable state interpreter works perfectly
// works fine
class AccountRepoMutableInterpreter extends AccountRepoInterpreter[Task] {
// mutable state
var table = Map.empty[String, Account]
// Natural transformation from Free Monad to Task is the interpreter
val interpreter = new (AccountRepoInstruction ~> Task) {
override def apply[A](fa: AccountRepoInstruction[A]): Task[A] = fa match {
// give meaning to each instruction
case Query(no) =>
Task.now(table.get(no).get)
case Store(acc) =>
Task.now(table = table + (acc.no -> acc)).void
case Delete(no) =>
Task.now(table = table - no).void
}
}
override def apply[A](instruction: AccountRepo[A]): Task[A] =
instruction.foldMap(interpreter)
}
import AccountService._
val testInterpreter = new AccountRepoMutableInterpreter
val account = Account("a-123", "John K")
val comp = for {
a <- store(account.copy(balance = Balance(1000)))
q <- query(account.no)
c <- delete(account.no)
_ <- store(account.copy(balance = Balance(2000)))
} yield ()
// interpret free instructions and give it meaning getting back a Task and execute it synchronously
testInterpreter(comp).unsafePerformSync
println(testInterpreter.table)
}
However, the state implementation fails to compile even though the types align correctly (according to IntelliJ
// does not work even though types align
class AccountRepoStateInterpreter extends AccountRepoInterpreter[AccountState] {
val interpreter = new (AccountRepoInstruction ~> AccountState) {
override def apply[A](fa: AccountRepoInstruction[A]): AccountState[A] = fa match {
case Query(no) =>
val errMsg: Err[(AccountMap, Account)] = -\/(new Error("could not find member"))
val result: AccountState[Account] = StateT[Err, AccountMap, Account] {
accountMap =>
accountMap.get(no) match {
case Some(acc) =>
\/-( (accountMap, acc) )
case None =>
errMsg
}
}
result
case Store(acc) =>
val result: AccountState[Unit] = StateT[Err, AccountMap, Unit] { accountMap =>
val updatedMap = accountMap + (acc.no -> acc)
\/-( (updatedMap, ()) )
}
result
case Delete(no) =>
val result: AccountState[Unit] = StateT[Err, AccountMap, Unit] { accountMap =>
val updatedMap = accountMap - no
\/-( (updatedMap, ()) )
}
result
}
}
override def apply[A](instruction: AccountRepo[A]): AccountState[A] = instruction.foldMap(interpreter)
}
Any idea what I'm missing here?
Thanks a lot
Here is the full example
import java.util.Date
import scala.language.higherKinds
import scalaz.concurrent.Task
object Example extends App {
import scalaz._
import Scalaz._
// https://github.com/debasishg/frdomain/tree/master/src/main/scala/frdomain/ch5/domain/model
import frdomain.ch5.domain.model._
// https://github.com/debasishg/frdomain/blob/master/src/main/scala/frdomain/ch5/domain/model/Account.scala#L10
import common._
case class Balance(amount: Amount = 0)
case class Account(no: String, name: String, dateOfOpening: Date = today, dateOfClosing: Option[Date] = None,
balance: Balance = Balance(0))
object Account {
implicit val showAccount: Show[Account] = Show.shows { case a: Account => a.toString }
}
sealed trait AccountRepoInstruction[+A]
case class Query(no: String) extends AccountRepoInstruction[Account]
case class Store(account: Account) extends AccountRepoInstruction[Unit]
case class Delete(no: String) extends AccountRepoInstruction[Unit]
type AccountRepo[A] = Free[AccountRepoInstruction, A]
trait AccountRepository {
def store(account: Account): AccountRepo[Unit] =
Free.liftF(Store(account))
def query(no: String): AccountRepo[Account] =
Free.liftF(Query(no))
def delete(no: String): AccountRepo[Unit] =
Free.liftF(Delete(no))
def update(no: String, update: Account => Account): AccountRepo[Unit] =
for {
acc <- query(no)
_ <- store(update(acc))
} yield ()
def updateBalance(no: String, amount: Amount, update: (Account, Amount) => Account): AccountRepo[Unit] =
for {
acc <- query(no)
_ <- store(update(acc, amount))
} yield ()
}
trait AccountService[Account, Amount, Balance] {
def open(no: String, name: String, openingDate: Option[Date]): AccountRepo[Account]
def close(no: String, closeDate: Option[Date]): AccountRepo[Account]
def debit(no: String, amount: Amount): AccountRepo[Account]
def credit(no: String, amount: Amount): AccountRepo[Account]
def balance(no: String): AccountRepo[Balance]
}
object AccountService extends AccountService[Account, Amount, Balance] with AccountRepository {
override def open(no: String, name: String, openingDate: Option[Date]) = {
for {
_ <- store(Account(no, name, openingDate.getOrElse(today)))
acc <- query(no)
} yield acc
}
override def close(no: String, closeDate: Option[Date]): AccountRepo[Account] = for {
_ <- update(no, acc => acc.copy(dateOfClosing = Some(today)))
a <- query(no)
} yield a
override def debit(no: String, amount: Amount): AccountRepo[Account] = for {
_ <- updateBalance(no, amount, (acc, am) => acc.copy(balance = Balance(acc.balance.amount - am)))
a <- query(no)
} yield a
override def credit(no: String, amount: Amount): AccountRepo[Account] = for {
_ <- updateBalance(no, amount, (acc, am) => acc.copy(balance = Balance(acc.balance.amount + am)))
a <- query(no)
} yield a
override def balance(no: String): AccountRepo[Balance] =
query(no).map(acc => acc.balance)
}
trait AccountRepoInterpreter[M[_]] {
def apply[A](instruction: AccountRepo[A]): M[A]
}
type AccountMap = Map[String, Account]
type Err[A] = Error \/ A
type AccountState[A] = StateT[Err, AccountMap, A]
// does not work even though types align
class AccountRepoStateInterpreter extends AccountRepoInterpreter[AccountState] {
val interpreter = new (AccountRepoInstruction ~> AccountState) {
override def apply[A](fa: AccountRepoInstruction[A]): AccountState[A] = fa match {
case Query(no) =>
val errMsg: Err[(AccountMap, Account)] = -\/(new Error("could not find member"))
val result: AccountState[Account] = StateT[Err, AccountMap, Account] {
accountMap =>
accountMap.get(no) match {
case Some(acc) =>
\/-( (accountMap, acc) )
case None =>
errMsg
}
}
result
case Store(acc) =>
val result: AccountState[Unit] = StateT[Err, AccountMap, Unit] { accountMap =>
val updatedMap = accountMap + (acc.no -> acc)
\/-( (updatedMap, ()) )
}
result
case Delete(no) =>
val result: AccountState[Unit] = StateT[Err, AccountMap, Unit] { accountMap =>
val updatedMap = accountMap - no
\/-( (updatedMap, ()) )
}
result
}
}
override def apply[A](instruction: AccountRepo[A]): AccountState[A] = instruction.foldMap(interpreter)
}
val stateInterpreter = new AccountRepoStateInterpreter
// works fine
class AccountRepoMutableInterpreter extends AccountRepoInterpreter[Task] {
// mutable state
var table = Map.empty[String, Account]
// Natural transformation from Free Monad to Task is the interpreter
val interpreter = new (AccountRepoInstruction ~> Task) {
override def apply[A](fa: AccountRepoInstruction[A]): Task[A] = fa match {
// give meaning to each instruction
case Query(no) =>
Task.now(table.get(no).get)
case Store(acc) =>
Task.now(table = table + (acc.no -> acc)).void
case Delete(no) =>
Task.now(table = table - no).void
}
}
override def apply[A](instruction: AccountRepo[A]): Task[A] =
instruction.foldMap(interpreter)
}
import AccountService._
val testInterpreter = new AccountRepoMutableInterpreter
val account = Account("a-123", "John K")
val comp = for {
a <- store(account.copy(balance = Balance(1000)))
q <- query(account.no)
c <- delete(account.no)
_ <- store(account.copy(balance = Balance(2000)))
} yield ()
// interpret free instructions and give it meaning getting back a Task and execute it synchronously
testInterpreter(comp).unsafePerformSync
println(testInterpreter.table)
}
I'm using Scala 7.2.8 and Scala 2.12.1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.