我想这样玩元组和镜头:
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)
K. A. Buhr's answer完全可以满足要求,所以这里只是一些花絮。由于magnify
只需要一个吸气剂(而不是一副成熟的镜头),就可以在myfct'
的帮助下用_1
和朋友表达ReifiedGetter
:
ReifiedGetter
这可能更接近您的伪代码,尽管不是特别符合人体工程学。