小编Gia*_*eri的帖子

使用 Scala cats 编写 MTL 风格代码的给定实例的问题

我正在尝试编写一些 Scala 代码以实现mtl 风格的自定义行为。例如,为了公开对特定效果进行抽象的“写入数据库”功能,我编写了自己的类型类:

trait CanPersist[M[_]]:
  def persistToDB[A](a: A): M[Unit]

given CanPersist[IO] with
  def persistToDB[A](a: A): IO[Unit] = IO(???) // Write to DB
Run Code Online (Sandbox Code Playgroud)

IO 实例可以轻松实现,但我感兴趣的是自动为任何基于 IO 的 monad 堆栈提供实例:

// If a Transformer wraps a Monad that can persist then it can persist too
given persistTA[M[_]: CanPersist: Monad, T[_[_], _]: MonadTransformer]:
  CanPersist[[A] =>> T[M, A]] with 
  def persistToDB[A](a: A): T[M, Unit] =
    summon[MonadTransformer[T]].lift(summon[CanPersist[M]].persistToDB(a))
Run Code Online (Sandbox Code Playgroud)

问题显然是 cats 没有定义自己的MonadTransformer类型类;幸运的是,自己编写非常简单:

trait MonadTransformer[T[_[_], _]]:
  def lift[M[_]: Monad, A](ma: M[A]): T[M, A] …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala monad-transformers scala-cats given

7
推荐指数
1
解决办法
460
查看次数

令人困惑的 ReaderT 定义

作为练习,我一直在重新实现一些常见的 monad 及其相应的转换器;以下是我定义的一些类型:

newtype Writer  w   a = Writer  { runWriter  :: (w, a) }
newtype WriterT w m a = WriterT { runWriterT :: m (Writer w a) }

newtype Maybe    a = Just a | Nothing
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
Run Code Online (Sandbox Code Playgroud)

据我所知,变压器将一个单子“包裹”在一个外部单子中m;遵循这种直觉,我尝试ReaderT以类似的方式定义变压器:

newtype Reader  r   a = Reader  { runReader  :: r -> a }
newtype ReaderT r m a = ReaderT { runReaderT :: m …
Run Code Online (Sandbox Code Playgroud)

monads haskell monad-transformers reader-monad

4
推荐指数
1
解决办法
219
查看次数