You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无函数依赖的MonadReader:是否有现成库实现?

无函数依赖的MonadReader解决方案

现成库选项

有现成库能满足需求:reader-simple。它提供的MonadReader类没有m -> r的函数依赖,允许同一个Monad实例同时满足多个不同r的MonadReader约束,完全适配你提到的约束组合场景。使用时ask可能需要类型注解(比如ask @A),但正如你所说,当ask的输出用途能明确类型时,类型推断也能自动推导,这个妥协完全可行。

自行实现方案

如果不想引入额外依赖,也可以自己定义无函数依赖的MonadReader类:

class Monad m => MonadReader r m where
  ask :: m r
  local :: (r -> r) -> m a -> m a

然后为你的上下文载体(比如ReaderT (A,B,C) m)实现多个实例:

instance Monad m => MonadReader A (ReaderT (A,B,C) m) where
  ask = asks (\(a,_,_) -> a)
  local f = mapReaderT (\(a,b,c) -> (f a, b, c))

instance Monad m => MonadReader B (ReaderT (A,B,C) m) where
  ask = asks (\(_,b,_) -> b)
  local f = mapReaderT (\(a,b,c) -> (a, f b, c))

instance Monad m => MonadReader C (ReaderT (A,B,C) m) where
  ask = asks (\(_,_,c) -> c)
  local f = mapReaderT (\(a,b,c) -> (a, b, f c))

这样就能直接组合你示例中的f和g,无需手动拆分重组元组上下文。

其他替代思路

除了上述两种方式,还可以考虑使用效应系统,比如polysemy或freer-effects。这类库的效应组合天然支持多个类似Reader的上下文需求,不需要依赖类型类的函数依赖就能实现灵活的上下文组合,不过学习成本会比直接用无函数依赖的MonadReader高一些。

内容的提问来源于stack exchange,提问作者Clinton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:32:19