atnos-org / eff Goto Github PK
View Code? Open in Web Editor NEWEff monad for cats - https://atnos-org.github.io/eff
License: MIT License
Eff monad for cats - https://atnos-org.github.io/eff
License: MIT License
Hi @etorreborre, both myself personally and REA are now building on top of Eff as a trusted platform.
One way we can strengthen the stability off Eff would be to include it in the Scala community build, so we'll know if future scala versions break it.
I work with Seth as Scala Swing module maintainer already, I'd be happy to volunteer as "build maintainer" for an Eff build.
I can send a PR to add Eff, just wanted to checkin with you first..?
Hey there, I've seen https://github.com/atnos-org/eff/blob/957fe5b514ee4afa6683fb803772234870749bb6/shared/src/main/scala/org/atnos/eff/AsyncFutureInterpreter.scala and I'm trying to figure out how to use fromFuture
.
I have a few methods returning Future
and I'd like to incorporate them inside my effect.
So, what I have so far is
val interpreter = {
import scala.concurrent.ExecutionContext.Implicits.global
AsyncFutureInterpreter.create
}
import interpreter._
def program[R : _config : _log : _async]: Eff[R, Future[String]] = for {
config <- ask[R, Config]
ip <- fromFuture(connect(config))
_ <- tell(s"Listening on ${config.host}:${config.port}")
} yield ip
and this compiles.
However, the fromFuture
method comes from import interpreter._
. So here I'm coupling the interpreter and the effect building.
Is there a way of working with existing futures in without coupling the specific interpreter?
Eval
is only used in eff-cats for abstraction over evaluation, and there is no mention of trampolining a computation inside Eff[R, A]
for R |= Eval
. This is because there is no equivalent in EvalCreation to Eval.defer
in cats.Eval
.
Edit: If this is done, I also recommend adding a comment to runEval
indicating that it does not preserve stack-safety.
type FMP = Fx.append[MP, Fx.fx2[Error, TimedFuture]]
works fine. However, if I do type FMP = Fx.append[Fx.fx2[Error, TimedFuture], MP]
I get the following compiler error:
Cannot prove that org.atnos.eff.Eff[org.atnos.eff.FxAppend[org.atnos.eff.Fx1[org.atnos.eff.TimedFuture],org.atnos.eff.NoFx],scala.util.Either[Throwable,Option[A]]] =:= org.atnos.eff.Eff[org.atnos.eff.Fx.fx1[org.atnos.eff.TimedFuture],scala.util.Either[Throwable,Option[A]]].
[error] .runAsync,
[error] ^
The introduction to this library might lead people into thinking that Kiselyov etc "invented" Eff, as it did me for a long time. In fact there was an explosion of different implementations of algebraic effects in the 2011 to 2013 timescale. But in my opinion, some credit for Eff should be attributed to Gordon Plotkin and Matija Pretnar whose theoretical work seems to have enabled them all.
This issue is to track some experimental hacking Ive been doing around
Supporting the ConcurrentEffect
typeclass from cats.effect 0.10 in IOEffect. This is a very speculative, "follow-the-types" implementation and I don't feel confident of its correctness or even sanity - any feedback most welcome. There's some gnarly transient mutable state to work around runIO
s inablity to thread non-Unit
values down the chain, inspired by @etorreborre hint on gitter last Nov
Law checking of the Async instance and this new ConcurrentEffect
using Discipline. On the laws
branch, cats/test
now runs law checks. One finding was that the existing Async fails 10 law checks, once around stack safety and nine times around seemingly not suspending thrown Throwables.
The story behind why I got interested in this area is that I will teach a second Eff workshop at Lambdajam this year. I want to update my material and try to teach whatever is contemporary "best-practice" as at 2018, and I think using cats.effect.IO with Eff would be a nice touch.
However that said, Ive already got the IO
effect working fine inside Eff stack, so getting these typeclasses law-checked/working is perhaps a bad habit of looking down passing rabbit-holes :P
CC @alexandru
Add a way to use a F ~> Union2[Fx.fx2[F, G], ?]
to use the info contained in F
's structure to add a G
effect to an effect stack already containing an F
. I'm thinking interpret.augment
but that's just an idea.
Consider this example for AsyncFutureInterpreterSpec
:
def e14 = {
var invocationsNumber = 0
val cache = ConcurrentHashMapCache()
type S = Fx.fx2[Memoized, Async]
val intAsync: Eff[S, Int] = asyncFork[S, String]("a").flatMap( x => asyncFork[S, Int]({ invocationsNumber += 1; 1 }))
def makeRequest = asyncMemoized("only once", intAsync)
(makeRequest >> makeRequest).runAsyncMemo(cache).runAsyncFuture must be_==(1).await
invocationsNumber must be_==(1)
}
Looks like flatMap
ping causes the result of the first async to be cached. I would expect 1
to be cached, however "a"
is cached instead:
[error] x Async calls with continuations can be memoized with a memo effect
[error] 'a' is not equal to '1' (AsyncFutureInterpreterSpec.scala:179)
eff version: 4.3.0 (also tried on 4.2.0)
scala version: 2.12.1 (tried LBS and TLS, also 2.11.8)
http://scastie.org/30603
sealed trait TestAlg[A]
def interp[R, U, A](effect: Eff[R, A])(implicit m: Member.Aux[TestAlg, R, U], c: _task[U]): Eff[U, A] = ???
type S = Fx.fx2[TimedTask, TestAlg]
type R = Fx.fx1[TimedTask]
def prg[R : _task](implicit R: TestAlg |= R): Eff[R, Int] = ???
val x0: Eff[S, Int] = prg[S]
interp(x0) // ok
val x1: Eff[R, Int] = interp(x0) // compiler explosion
[error] AdaptTypeError - foundType is Erroneous: org.atnos.eff.Member[Product with Serializable,org.atnos.eff.Fx2[Product with Serializable,Product with Serializable]]{type Out = org.atnos.eff.Fx1[<error>]}
Hi, as I see in the source code, there is already updated version of cats-effect to 1.1.0.
Are there any plans on releasing it? Or maybe it is already available somehow?
It missing from the standard built ins
Is there a reason for this? Its inconsistent and a bit confusing for newcomers.
On the other hand, if no one has noticed/complained, yet maybe it suggests dropping Error effect and consolidating around Either effect..
https://github.com/atnos-org/eff-cats/blob/master/project/build.scala#L88
I assume you ment:
<connection>scm:git:http://[email protected]/etorreborre/eff-cats.git</connection>
Would you be interested in having support for Doobie effects (i.e., ConnectionIO
)? Or is this out of the scope of the project? I have been playing with this idea and currently have the below interpreter as a proof of concept (requiring as last effect on the task Task
). It currently rewrites in terms of monix.eval.Task
but this would of course be generalized. The interpreter also handles errors, calling the configured Strategy
ConnectionIO programs of the Doobie transactor, which are by default:
before
(set autoCommit false)after
(commit)oops
(rollback)always
(connection close)type TaskStack = Fx.fx1[Task]
def runConnectionIO(t: Transactor[Task, HikariDataSource])(
implicit m1: Member.Aux[ConnectionIO, R, Fx.fx1[Task]]): Eff[TaskStack, A] = {
for {
c <- send[Task, TaskStack, Connection](t.connect(t.kernel))
res <- {
val eInterpreted: Eff[TaskStack, A] = {
interpret.translate(e)(new Translate[ConnectionIO, TaskStack] {
override def apply[X](kv: ConnectionIO[X]): Eff[TaskStack, X] = {
TaskCreation.fromTask(kv.foldMap(t.interpret).run(c))
}
})
}
val beforeAfter: Task[A] = for {
_ <- t.strategy.before.foldMap(t.interpret).run(c)
res <- eInterpreted.into[TaskStack].runSequential
_ <- t.strategy.after.foldMap(t.interpret).run(c)
} yield res
val always = t.strategy.always.foldMap(t.interpret).run(c)
val oops = t.strategy.oops.foldMap(t.interpret).run(c)
send[Task, TaskStack, A](
beforeAfter
.recoverWith({ case err => oops *> Task.raiseError[A](err) })
.doOnFinish(_ => always)
.doOnCancel(oops *> always)
)
}
} yield res
}
seems like only 2.11 version is published. Could you please publish 2.12 version?
Thanks
Is it something you consider? I can probably work on a PR due to our need.
I often struggle with browsing the eff documentation. At the same time, contributing to the documentation is not straightforward.
Any plans on moving to sbt-microsites
(which also uses tut
)?
We are unable to get TimedFuture
to do any work concurrently after we upgraded from 3.0.4. I have created the reproducible test cases at :-
Despite having enough threads, the futures seems to be executing sequentially after we upgrade from 3.0.4 to 4.0.2. We have attached YourKit thread images in those repos.
Is this is bug or are we using the library wrong in some way?
Another point to note is that the following code where we use TimedFutures directly (rather than being translated into) works fine on 4.2.0 :-
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import java.util.concurrent.Executors
import cats.implicits._
import org.atnos.eff._
import org.atnos.eff.Interpret.translate
import org.atnos.eff.future._
import org.atnos.eff.all._
import org.atnos.eff.syntax.all._
import org.atnos.eff.syntax.future._
object Test {
def q(i: Int, sleep: Long) = for {
_ <- p(i, 0, sleep)
_ <- p(i, 1, sleep)
_ <- p(i, 2, sleep)
} yield ()
def p(i: Int, j: Int, sleep: Long) = futureDelay {
println(s"Starting $i-$j")
Thread.sleep(sleep)
println(s"Finished $i-$j")
}
type T = Fx.fx1[TimedFuture]
val x = Eff.traverseA[T, List, Int, Unit](List(1, 2, 3, 4))(i => q(i, 10000))
def main(args: Array[String]): Unit = {
implicit val scheduler = ExecutorServices.schedulerFromScheduledExecutorService(Executors.newSingleThreadScheduledExecutor())
Await.result(
x.runAsync,
5 minutes
)
}
}
I started out seeing strange order-dependence in a non open source codebase using a Fx.fx6
stack, as others had reported on gitter, for code that IIRC worked fine on 1.7.x. Got it to compile and run by interpreting in this order: Option, State, State, Reader, Writer, Xor.
So I tried to simplify the problem down in an ammonite repl, but saw alot of more basic errors for things that I thought should work: https://gist.github.com/benhutchison/720fcea4e03692bef383b3c05694981a
over in the Scala community build I'm trying to get all the Typelevel ducks in a row at scala/community-build#775, having eff do this upgrade would help with that
There should be an error effect interpreter that allows one to use a Semigroup
to accumulate errors during traverse
calls, instead of failing immediately (a là cats.data.Validated
).
@etorreborre Can you do a 5.2 release in the next few days?
I want to showcase some Eff w Monix 3.0-RC1 features at Melbourne Scala meetup next Tuesday and it'd be nice if the audience can follow along if they want.
When creating an AsyncFutureInterpreter
using this method a pair of ExecutorService
and ScheduledExecutorService
is being created, using lots of threads potentially.
This is caused by the fact that ExecutionContext
is never used here.
attempting to use it results in
Downloading sbt launcher for 1.1.4:
From http://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/1.1.4/sbt-launch.jar
To /Users/tisue/.sbt/launchers/1.1.4/sbt-launch.jar
Download failed. Obtain the jar manually and place it at /Users/tisue/.sbt/launchers/1.1.4/sbt-launch.jar
you could either update to a more recent sbt-extras, or just not have a launch script in the repo at all, most open source Scala projects don't
Suppose I have a Stack like
type LogWriter[A] = Writer[LogEntry, A]
type Result[+A] = Either[LogicError, A]
type RequestIdReader[A] = Reader[RequestId, A]
type Stack = Fx.fx4[LogWriter, Async, Result, RequestIdReader]
and some convenience type aliases
type _log[R] = LogWriter |= R
type _async[R] = Async |= R
type _result[R] = Result |= R
type _requestId[R] = RequestIdReader |= R
Now, in some parts of my application I know that I will be working with that specific stack, so for instance instead of
def someMethod[R: _log : _async : _result : _requestId](someParam: Int): Eff[R, Int] = ???
I would like to specify Stack
directly. Something like
def someMethod[R: Stack](someParam: Int): Eff[Stack, Int] = ???
Clearly this doesn't work, but I can't figure out a syntax for expressing this.
Is there a concise way to say that multiple effects (all the ones that compose my Stack
) are member of a stack?
import cats._, data._
import org.atnos.eff._
type ReaderInt[A] = Reader[Int, A]
type WriterString[A] = Writer[String, A]
type Stack = Fx.fx3[WriterString, ReaderInt, Eval]
import org.atnos.eff.all._
import org.atnos.eff.syntax.all._
// useful type aliases showing that the ReaderInt and the WriterString effects are "members" of R
// note that R could have more effects
type _readerInt[R] = ReaderInt |= R
type _writerString[R] = WriterString |= R
def program[R :_readerInt :_writerString :_eval]: Eff[R, Int] = for {
// get the configuration
n <- ask[R, Int]
// log the current configuration value
_ <- tell("the required power is "+n)
// compute the nth power of 2
a <- delay(math.pow(2, n.toDouble).toInt)
// log the result
_ <- tell("the result is "+a)
} yield a
// run the action with all the interpreters
// each interpreter running one effect
program[Stack].runReader(6).runWriter.runEval.run
After compilation get:
No instance found for Member[[β$0$]cats.data.Kleisli[[A]A,Int,β$0$], A$A57.this.Stack].
The effect [β$0$]cats.data.Kleisli[[A]A,Int,β$0$] is not part of the stack A$A57.this.Stack
or it was not possible to determine the stack that would result from removing [β$0$]cats.data.Kleisli[[A]A,Int,β$0$] from A$A57.this.Stack
program[Stack].runReader(6).runWriter.runEval.run;}
^
What i do wrong? I took this example from introduction http://atnos-org.github.io/eff/org.atnos.site.Introduction.html
Hi,
I have a number of DSLs (which were written using Eff) that all translate to _throwableEither. All of the translation happens during interpretation - the DSLs themselves do not have any dependency on _throwableEither only their interpreters do.
I want to provide a way for users of the DSLs to handle lefts. However, catchLeft doesn't help capturing this. Is there some way to do this without changing the DSLs? It is okay for DSL users to explicitly specify requirement of _ThrowableEither in the effect stack.
Apologies if I am not following protocol its my first post here. Also, I am very new to Eff and Scala.
-vivek
I am relatively new to Scala (with Java background) and I am teaching myself Functional Programming. I am working my way through your tutorials.
My problem is that I am only able to get them running through the command line REPL. I have been trying to take the (simple) step of inserting each of the tutorials into a file within IntelliJ IDEA so that they print results to the console. My problem is they won't compile without errors, and I don't know why.
For example, taking code from the "Introduction" here is the file I have created:
class Tutorial{
}
object Intro extends App {
import cats._
import cats.data._
import org.atnos.eff._
type ReaderInt[A] = Reader[Int, A]
type WriterString[A] = Writer[String, A]
type Stack = Fx.fx3[WriterString, ReaderInt, Eval]
import org.atnos.eff.all._
import org.atnos.eff.syntax.all._
// useful type aliases showing that the ReaderInt and the WriterString effects are "members" of R
// note that R could have more effects
type _readerInt[R] = ReaderInt |= R
type _writerString[R] = WriterString |= R
def program[R: _readerInt : _writerString : _eval]: Eff[R, Int] = for {
// get the configuration
n <- ask[R, Int]
// log the current configuration value
_ <- tell("the required power is " + n)
// compute the nth power of 2
a <- delay(math.pow(2, n.toDouble).toInt)
// log the result
_ <- tell("the result is " + a)
} yield a
println(program[Stack].runReader(6).runWriter.runEval.run)
}
The compiler error is in the last line: "Cannot resolve symbol 'run'". I have tried many other approaches and structures, and they all give this error, or some other "Cannot resolve..." error.
I have already tried the "clear cache" fix, with restart of IntelliJ IDEA.
Can anyone help?
Raising this as a discussion - there's not a clear cut solution.
monix.execution.Scheduler
is a core abstraction in Monix that you find yourself passing around.
Generally I tend to use wildcard imports of Eff because I use Eff heavily and like to get early warning if there's clashes with other libraries I commonly use. I noticed that recently, the Eff package has added Scheduler which collides with Monix.
Eff's own Scheduler
type is pretty young, I wonder if there's scope to migrate it to a less collision-prone name?
I am trying to do
XorT.pure(eff)
where
eff: Eff[SomeEffect, Validated[E, A]]
and I get the following errors:
[error] both value listInstance in trait ListInstances of type => cats.Traverse[List] with cats.MonadCombine[List] with cats.CoflatMap[List]
[error] and value optionInstance in trait OptionInstances of type => cats.Traverse[Option] with cats.MonadCombine[Option] with cats.CoflatMap[Option] with cats.Alternative[Option]
[error] match expected type cats.Applicative[F]
[error] XorT.pure(s)
This is very weird since my Eff type has nothing to do with Option nor List. Weirdly if I do this:
XorT.pure(s)(optionInstance)
it compiles
So while running benchmarks is a good thing overall leaving scalameter as a runtime dependency with it's transitive dependencies isn't quite so good. Scalameter depends on jackson, scalachart, commons-math and on and on. Yes, I can exclude scalameter my dependencies but I really shouldn't have to. Perhaps a slight refactoring to put the benchmarks in their own package is in order.
Add a catchWrong
method to Validate
similar to catchLeft
in Xor
.
The signature could be something like:
catchLeft(r: Eff[R,A], handle: NonEmptyList[E] => Eff[R,A])(implicit m: Validate[E, ?] |= R): Eff[R, A]
Becasue withFilter
is apparently not a member of Eff
, you can not do pattern matching from the monadic flow syntax.
scala> import org.atnos.eff._
import org.atnos.eff._
scala> import org.atnos.eff.all._
import org.atnos.eff.all._
scala> import org.atnos.eff.syntax.all._
import org.atnos.eff.syntax.all._
scala> def f[R](x: (String, String)): Eff[R, String] = for { (a, b) <- pure(x) } yield a + b
<console>:23: error: value withFilter is not a member of org.atnos.eff.Eff[R,(String, String)]
def f[R](x: (String, String)): Eff[R, String] = for { (a, b) <- pure(x) } yield a + b
^
<console>:23: error: type mismatch;
found : Any
required: String
def f[R](x: (String, String)): Eff[R, String] = for { (a, b) <- pure(x) } yield a + b
scala> def f[R](x: String): Eff[R, String] = for { a: String <- pure(x) } yield a
<console>:23: error: value withFilter is not a member of org.atnos.eff.Eff[R,String]
def f[R](x: String): Eff[R, String] = for { a: String <- pure(x) } yield a
^
scala> def f[R](x: String): Eff[R, String] = for { a <- pure(x) } yield a
f: [R](x: String)org.atnos.eff.Eff[R,String]
Hi,
I've recently been starting to use eff. And it's amazing, thanks for building this!
However what keeps bugging me is that it leads to fairly long method signatures for monad stacks with many effects
def foo[R : _foo : _bar : _baz : ...](myArg: MyInputType): MyOutputType
Is there an established best practice for defining aliases for long chains of effect context bounds? If so, could you please add that to the documentation?
Thanks!
IndexOutOfBoundsException: 1
at org.atnos.eff.macros.EffMacros$$anonfun$4.applyOrElse(EffMacros.scala:119)
when trying to do so.Member
and MemberIn
type aliases when defined as aliases of |=
and <=
respectively. Atm it just claims that they are not provided.Hi Eric,
I'm currently puzzled a bit with understanding the proper usage of both Eff and fs2.Stream API.
What I want to do (let's assume some synthetic situation):
def getEffects[S: _io : _option]: Eff[S, Int] = Eff.pure(1)
type Stack = Fx2[IO, Option]
Stream.eval(getEffect[Stack])
.compile
.toList
.runOption
.unsafeRunSync
and apparently it fails with
could not find implicit value for parameter compiler: fs2.Stream.Compiler[[x]org.atnos.eff.Eff[Stack,x],G]
[error] val res: Eff[Stack, List[Int]] = Stream.eval(getEffect[Stack]).compile.toList
According to fs2 documentation, adding the instance of cats.effect.Effect helps, but i have a problem with writing the actual implementation of some functions:
implicit def effectEff[R]: cats.effect.Effect[Eff[R, ?]] = new cats.effect.Effect[Eff[R, ?]] {
override def runAsync[A](fa: Eff[R, A])(cb: Either[Throwable, A] => IO[Unit]): SyncIO[Unit] = ???
override def async[A](k: (Either[Throwable, A] => Unit) => Unit): Eff[R, A] = ???
override def asyncF[A](k: (Either[Throwable, A] => Unit) => Eff[R, Unit]): Eff[R, A] = ???
override def suspend[A](thunk: => Eff[R, A]): Eff[R, A] = {
fromIO(IO(thunk)).flatten
}
override def bracketCase[A, B](acquire: Eff[R, A])(use: A => Eff[R, B])(release: (A, ExitCase[Throwable]) => Eff[R, Unit]): Eff[R, B] = {
Eff.bracketLast(acquire)(use)(a => release(a, ExitCase.complete[Throwable]))
}
override def flatMap[A, B](fa: Eff[R, A])(f: A => Eff[R, B]): Eff[R, B] = fa.flatMap(f)
override def tailRecM[A, B](a: A)(f: A => Eff[R, Either[A, B]]): Eff[R, B] =
Eff.EffMonad[R].tailRecM(a)(f)
override def raiseError[A](e: Throwable): Eff[R, A] = ???
override def handleErrorWith[A](fa: Eff[R, A])(f: Throwable => Eff[R, A]): Eff[R, A] =
ioAttempt(fa).flatMap {
case Left(t) => f(t)
case Right(a) => Eff.pure(a)
}
override def pure[A](x: A): Eff[R, A] = Eff.pure(x)
}
Looking into the type signatures now I'm wondering does it even make any sense?
Current Eff API allows putting an Eff sub-program into a Monix Task effect:
def taskSuspend[R :_task, A](task: =>Task[Eff[R, A]], timeout: Option[FiniteDuration] = None): Eff[R, A]
But I am unclear how to obtain precise control of "forking" - specifically ExecutionModel - for Eff tasks. Motivation is to allow tasks collections to execute concurrently.
Discussion on gitter showed how to fork all Tasks in an Eff program. Experiment confirmed concurrent execution works.
But Monix docs describe forking as inserting an "Async boundary" between two tasks. An attempt to write this as an Eff program did not execute concurrently. The idea is:
fromTask(Task.unit.asyncBoundary) >> taskDelay(println(s"Im on ${Thread.currentThread}"))
Would like to understand & document how to write an Eff program with an Async Boundary that enables concurrent execution of Eff-subprograms.
It not clear that this is an Eff "framework", versus "Eff ecosystem" issue, but Im entering it here to keep track of this open question.
In the tutorial, there are a lot of places with "no file found at..." instead of sample code blocks, for example no file found at ../jvm/src/test/scala/org/atnos/site/snippets
in the "Create an ADT representing your grammar" section.
There are several "no file found at ..." errors showing in the Tutorial page at http://atnos-org.github.io/eff/org.atnos.site.Tutorial.html
Some background: back in June I asked if it were possible to weaken a State effect down to a Reader, for pieces of code that only read some state, but do not write it back. IIRC @etorreborre showed me a technique on eff-cats gitter, which I started using a version of. Its requires extending the stack with a new Reader
effect , which is syntactically a bit clumsy it did meet the goal.
Since the 2.0 upgrade I cant get it to work, when there are other effects that need be in the stack. The prepend
operation seems to hide the other effects in some way. The gist below is an attempt to simplify down a reproducible case of the problem Im hitting.
https://gist.github.com/benhutchison/b5d8267a764a22ca893af078ba3a3a27
I have this mixed-in thru a package object:
implicit class Id[A](val a: A) {
def pureEff[E]: Eff[E, A] = EffMonad[E].pure(a)
}
I find it regularly useful, allows type A
to be inferred. I chose pureEff
rather than pure
because of name collision.
I think we should be able to provide a Traverse
instance for Eff[S, A]
, given that all of the members of S
have Traverse
instances; by this I mean that all of them are possible to run
without detach
.
I've got an example that compiles but throws a head error. The only thing different from the example is the interpreter looks different (less raw) and we can't combine all the effects. In the example there are two effects getUser and getUsers, all of which can be combined. This example adds something orthogonal that cannot be be combined.
Below is an example of it throwing.
https://gist.github.com/dispalt/28ece72e3bace1dece4b1edd6e4706a8
Along with Scala Future, Scalaz Task and Monix Task I think it would be useful to provide integration (Async effect) with twitter util future. I've just started playing with Eff and I believe that I do not have enough expertise with Eff to implement it myself correctly (at least right now and fast :) ) But I'm ready to take a shot if no one will pick this up in the near future.
Hi!
Does it makes sense to have something like this in the library (transforming a Kleisli into the target effect if it's part of the stack):
def translateKleisli[T[_], R, U, S, A](e: Eff[R, A], s: S)(
implicit mx: Member.Aux[Kleisli[T, S, ?], R, U],
m: T |= U): Eff[U, A] =
interpret.translate(e) {
new Translate[Kleisli[T, S, ?], U] {
override def apply[X](kv: Kleisli[T, S, X]): Eff[U, X] = {
send[T, U, X](kv.run(s))
}
}
}
I only saw support for Reader
(which is Kleisli
with Id
as an effect) in the library and I wondered if there was a particular reason for this (I thought I'd ask before preparing a PR).
Thanks for the effort by the way, really like this library!
seen at e.g. https://scala-ci.typesafe.com/view/scala-2.12.x/job/scala-2.12.x-integrate-community-build/3177/
[eff] [info] EffApplicativeSpec
[eff] [error] x uses the applicative "sequencing" whereas >> uses the monadic sequencing
[eff] [error]
[eff] [error] action1
[eff] [error] action2
[eff] [error] - action1
[eff] [error] + action2
[eff] [error] - action2
[eff] [error] + action1 (EffApplicativeSpec.scala:52)
[eff] [info] This means that *> will discard the left result but can still run 2 actions concurrently
[eff] [info] + Eff values can be traversed with an applicative instance
[eff] [info] + Eff.traverseA is stacksafe
[eff] [info] + Eff.traverseA preserves concurrency
[eff] [info] + Applicative calls can be optimised by "batching" requests
[eff] [info] Interleaved applicative calls can be interpreted properly
[eff] [info] + with no natural interpretation (see release notes for 4.0.2)
[eff] [info] + with a natural interpretation (see release notes for 4.4.2)
[eff] [info] Total for specification EffApplicativeSpec
[eff] [info] Finished in 360 ms
[eff] [info] 7 examples, 1 failure, 0 error
I noticed that the Task docs I added to the main effects menu dont appear for me at http://atnos-org.github.io/eff/org.atnos.site.OutOfTheBox.html
Has the site just not been republished?
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.