首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用ZIO解释最终的无标记DSL?

如何用ZIO解释最终的无标记DSL?
EN

Stack Overflow用户
提问于 2020-12-07 23:10:01
回答 2查看 190关注 0票数 0

我有最后一个无标记DSL来构建简单的数学表达式:

代码语言:javascript
复制
trait Entity[F[_]] {
  def empty: F[Int]
  def int(value: Int): F[Int]
}

trait Operation[F[_]] {
  def add(a: F[Int], b: F[Int]): F[Int]
}

我想实现一个ZIO解释器。基于module-pattern 指南,可能的实现如下所示:

代码语言:javascript
复制
type Entity = Has[Entity[UIO]]

object Entity {
  val test: ULayer[Entity] =
    ZLayer.succeed {
      new Entity[UIO] {
        override def empty: UIO[Int] =
          ZIO.succeed(0)

        override def int(value: Int): UIO[Int] =
          ZIO.succeed(value)
      }
    }

  def empty: URIO[Entity, Int] =
    ZIO.accessM(_.get.empty)

  def int(value: Int): URIO[Entity, Int] =
    ZIO.accessM(_.get.int(value))
}

type Operation = Has[Operation[UIO]]

object Operation {
  val test: ULayer[Operation] =
    ZLayer.succeed {
      new Operation[UIO] {
        override def add(a: UIO[Int], b: UIO[Int]): UIO[Int] =
          ZIO.tupled(a, b).map { case (x, y) => x + y }
      }
    }

  def add(a: UIO[Int], b: UIO[Int]): URIO[Operation, Int] =
    ZIO.accessM(_.get.add(a, b))
}

使用此实现构建表达式时,必须像这样反复调用provideLayer

代码语言:javascript
复制
Operation.subtract(
  Entity.empty.provideLayer(Entity.test),
  Entity.int(10).provideLayer(Entity.test)
).provideLayer(Operation.test)

看上去更像是反模式。什么是最惯用或最ZIO的方式来解释DSL?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-18 07:07:57

回到这个问题,更好地理解ZIO,我找到了一个解决方案。这是一个解决办法,不符合ZIO的精神,尽管如此,我认为这可能是值得分享的。

我更新了ZIO的业务执行情况:

代码语言:javascript
复制
type Operation = Has[Service[URIO[Entity, *]]]

object Operation {
  val live: ULayer[Operation] =
    ZLayer.succeed {
      new Service[URIO[Entity, *]] {
        override def add(a: URIO[Entity, Int])(b: URIO[Entity, Int]): URIO[Entity, Int] =
          a.zip(b).map { case (x, y) => x + y }
      }
    }
}

def add(a: URIO[Entity, Int])(b: URIO[Entity, Int]): URIO[Entity with Operation, Int] =
  ZIO.accessM(_.get[Service[URIO[Entity, *]]].add(a)(b))

这样,实体和操作就可以这样组合起来了:

代码语言:javascript
复制
operation.add(entity.int(5))(entity.int(37))
票数 0
EN

Stack Overflow用户

发布于 2020-12-07 23:52:18

从这个问题上还不太清楚你想达到什么目的,但让我来回答。

  1. ZIO的R参数与构建DSL没有直接关系。一旦构建了DSL,R可能会帮助您以人机工程学的方式将其传递给计算(但可能不会)。
  2. DSL不是一个确切的术语,但ZIO不太可能帮助您构建它。DSL通常基于简单的自省数据类型(所谓的初始编码)或带有大量F(最终编码)的抽象数据类型。ZIO数据类型既不是抽象的,也不是内省的。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65190776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档