是否存在定义(a→m b)转换为m(a→b)函数的Typeclass?相关库查询
关于
a -> m b转m (a -> b)的Typeclass及库支持 你定义的shift函数对应的是交换函子与箭头顺序的操作,Haskell生态里有现成的Distributive typeclass(来自distributive包)正好提供这个能力,它的核心函数distribute的类型签名和你的shift完全一致:
distribute :: Distributive f => (a -> f b) -> f (a -> b)
关键说明:
Distributive比你定义的MonadShift更通用:它不需要Monad约束,只要求f是可分配的函子,覆盖场景更广。- 你实现的
Identity、ReaderT r m实例,distributive包已经为所有符合条件的函子提供了现成实现,无需重复编写。
示例用法
import Data.Distributive (Distributive(distribute)) import Control.Monad.Reader (Reader, runReader) import Data.Functor.Identity (Identity, runIdentity) -- Identity实例对应用法 identityExample :: Identity (Int -> String) identityExample = distribute (\x -> Identity (show x)) -- ReaderT实例对应用法 readerExample :: Reader String (Int -> String) readerExample = distribute (\x -> Reader (\r -> show x ++ r))
如果你的场景确实需要绑定Monad约束,也可以基于Distributive封装自己的MonadShift,但大多数场景下直接使用Distributive会更灵活。
内容的提问来源于stack exchange,提问作者Hexirp
相关产品推荐
相关产品推荐

