Giter Site home page Giter Site logo

Macro improvements about eff HOT 6 CLOSED

atnos-org avatar atnos-org commented on July 18, 2024 2
Macro improvements

from eff.

Comments (6)

mahe-ymc avatar mahe-ymc commented on July 18, 2024

I have one more on my wishlist:

  • eff macro should extend an already existing companion object instead of overwriting it

from eff.

msiegenthaler avatar msiegenthaler commented on July 18, 2024

Also regarding the macro:

from eff.

msiegenthaler avatar msiegenthaler commented on July 18, 2024

Here is a way to get rid of the need to generate a repetition of Translators (Translation1, Translator2, ..).

Library classes

Translator and Translator1..Translator10

trait Translator {
  type For[_]
  protected type _effects[R]

  protected def translate[R, U, X](a: For[X])(implicit auth: Member.Aux[For, R, U],
    e: _effects[U]): Eff[U, X]

  protected type Handler
  protected val handler: Handler
}
package lib.eff

import scala.language.higherKinds
import org.atnos.eff._

trait Translator1[Effect[_]] extends Translator {
  protected type _effect[R] = Effect |= R
  protected type _effects[R] = _effect[R]

  def run[R, U, A](e: Eff[R, A])
    (implicit auth: Member.Aux[For, R, U],
      e1: _effect[U]): Eff[U, A] =
    interpret.translate(e)(new Translate[For, U] {
      def apply[X](a: For[X]): Eff[U, X] = translate(a)
    })
}
package lib.eff

import scala.language.higherKinds
import org.atnos.eff._

trait Translator2[Effect1[_], Effect2[_]] extends Translator {
  protected type _effect1[R] = Effect1 |= R
  protected type _effect2[R] = Effect2 |= R

  /** So we can just use <code>def xxx[R: _effects]</code> to have all effects. */
  protected sealed trait _effects[R] {
    val effects: (_effect1[R], _effect2[R])
  }
  protected object _effects {
    implicit def create[R](implicit
      e1: _effect1[R], e2: _effect2[R]): _effects[R] = new _effects[R] {
      val effects = (e1, e2)
    }
  }
  protected implicit def extractEffect1[R](implicit effects: _effects[R]): _effect1[R] =
    effects.effects._1
  protected implicit def extractEffect2[R](implicit effects: _effects[R]): _effect2[R] =
    effects.effects._2

  def run[R, U, A](e: Eff[R, A])
    (implicit auth: Member.Aux[For, R, U],
      e1: _effect1[U],
      e2: _effect2[U]): Eff[U, A] =
    interpret.translate(e)(new Translate[For, U] {
      def apply[X](a: For[X]): Eff[U, X] = translate(a)
    })
}

... and so on ...

Generate in macro

Example for an "Auth" effect with one action (VerifyToken):

trait AuthPortTranslator extends Translator {
  type For[A] = Auth[A]

  protected def translate[R, U, X](a: Auth[X])
    (implicit auth: Aux[Auth, R, U], e: _effects[U]): Eff[U, X] = a match {
    case VerifyToken(token) => handler.verifyToken(token)
  }

  protected trait Handler {
    def verifyToken[U: _effects](token: BearerToken): Eff[U, Option[User]]
  }
}

Write Translator

the implementor now writes a translator like this. Note the extends that combines the desired number of target effects and the source effect.

package auth.adapter.inmemory

import auth.adapter.AuthPortTranslator
import auth.domain.{BearerToken, User, UserId}
import cats.data.State
import lib.eff.Translator1
import org.atnos.eff.all._

object AuthInMemory extends AuthPortTranslator with Translator1[State[AuthState, ?]] {
  def empty: AuthState = AuthState()

  protected val handler = new Handler {
    def verifyToken[U: _effects](token: BearerToken) = {
      get.map { state =>
        state.tokens.get(token).flatMap(state.users.get)
      }
    }
  }
}

from eff.

etorreborre avatar etorreborre commented on July 18, 2024

@msiegenthaler Hi Mario, do you want to give it a go in a PR? In the meanwhile we can leave this issue for fixing the original problem, which is the exception on smart constructors with no parameters lists.

from eff.

etorreborre avatar etorreborre commented on July 18, 2024

@2chilled @mahe-ymc sorry for the long wait, your suggestions have been implemented as part of 4.4.4.

from eff.

mahe-ymc avatar mahe-ymc commented on July 18, 2024

@etorreborre No worries! Thanks for improving this :)

from eff.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.