通过 ReaderT 获取带镜头的元组子集
getting a tuple subset with lens over a ReaderT
我想这样玩元组和镜头:
myfct :: ReaderT (a,b,c,d,e) m a -> ReaderT (a,c,d) m a
myfct = zoom ...
能够将输入元组修改为其子集...
伪代码应该是这样的:
zoom (_1,_3,_4)
如@dfeuer 所述,您可能打算写:
myfct' :: Monad m => ReaderT (a,c,d) m a -> ReaderT (a,b,c,d,e) m a
这采取了一个只需要访问上下文 (a,c,d)
的操作,并将其提升为一个可以 运行 在提供 (a,b,c,d,e)
的更大上下文中的操作。这可以使用 magnify
编写,如下所示:
myfct' = magnify . to $ \(a,_,c,d,_) -> (a,c,d)
另一方面,如果您的意思是您所写的:
myfct :: Monad m => ReaderT (a,b,c,d,e) m a -> ReaderT (a,c,d) m a
然后你将不得不解释这应该做什么。特别是,如果您有访问 b :: String
组件的操作:
action :: Reader (Int,String,Int,Int,Int) Int
action = asks $ \(_,b,_,_,_) -> length (b :: String)
你想如何在没有 b :: String
的情况下 运行 它?
test' :: Int
test' = runReader (myfct action) (1,2,3)
perfectly suffices, so here goes just a little tidbit. Since magnify
need just a getter (rather than a full-blown lens) one might express myfct'
in terms of _1
and friends with the help of ReifiedGetter
:
myfct' :: Monad m => ReaderT (a,c,d) m a -> ReaderT (a,b,c,d,e) m a
myfct' = magnify (runGetter $ (,,) <$> Getter _1 <*> Getter _3 <*> Getter _4)
虽然不是特别符合人体工程学,但这可能更接近您的伪代码的精神。
我想这样玩元组和镜头:
myfct :: ReaderT (a,b,c,d,e) m a -> ReaderT (a,c,d) m a
myfct = zoom ...
能够将输入元组修改为其子集...
伪代码应该是这样的:
zoom (_1,_3,_4)
如@dfeuer 所述,您可能打算写:
myfct' :: Monad m => ReaderT (a,c,d) m a -> ReaderT (a,b,c,d,e) m a
这采取了一个只需要访问上下文 (a,c,d)
的操作,并将其提升为一个可以 运行 在提供 (a,b,c,d,e)
的更大上下文中的操作。这可以使用 magnify
编写,如下所示:
myfct' = magnify . to $ \(a,_,c,d,_) -> (a,c,d)
另一方面,如果您的意思是您所写的:
myfct :: Monad m => ReaderT (a,b,c,d,e) m a -> ReaderT (a,c,d) m a
然后你将不得不解释这应该做什么。特别是,如果您有访问 b :: String
组件的操作:
action :: Reader (Int,String,Int,Int,Int) Int
action = asks $ \(_,b,_,_,_) -> length (b :: String)
你想如何在没有 b :: String
的情况下 运行 它?
test' :: Int
test' = runReader (myfct action) (1,2,3)
magnify
need just a getter (rather than a full-blown lens) one might express myfct'
in terms of _1
and friends with the help of ReifiedGetter
:
myfct' :: Monad m => ReaderT (a,c,d) m a -> ReaderT (a,b,c,d,e) m a
myfct' = magnify (runGetter $ (,,) <$> Getter _1 <*> Getter _3 <*> Getter _4)
虽然不是特别符合人体工程学,但这可能更接近您的伪代码的精神。