镜头:变焦新型
Lens: zooming newtype
我有兴趣为我的 monad 转换器堆栈获取 缩放 功能,该功能按以下方式定义:
newtype Awesome a = Awesome (StateT AwesomeState (ExceptT B.ByteString IO) a)
deriving (Functor, Applicative, Monad
, MonadIO, MonadError B.ByteString
, MonadState AwesomeState)
我的 AwesomeState 是深度嵌套的记录,所以使用缩放对我更新一些字段有很大帮助。但问题是缩放对于我的新类型来说不是开箱即用的。
Couldn't match type ‘Control.Lens.Internal.Zoom.Zoomed Awesome’
with ‘Control.Lens.Internal.Zoom.Zoomed m0’
我找到了一个示例,说明如何制作 Zoom 的自定义新类型 RWST 实例,但尝试使其适应我的新类型却没有结果
可以在此处找到 RWST 示例:http://lpaste.net/87737
有什么方法可以让我开始使用我的 monad 转换器堆栈进行缩放吗?为了实现这一目标,我需要做什么?如果我应该像 RWST 示例中那样实现 Zoomed/Zoom,那么我需要一个关于如何实现的指针,因为我尝试过但失败了。
我建议明确 Awesome
的状态:
{-# LANGUAGE TemplateHaskell, GeneralizedNewtypeDeriving, TypeFamilies,
FlexibleInstances, FunctionalDependencies #-}
import Control.Applicative
import Control.Monad.Error
import Control.Monad.State
import Control.Lens
import Control.Lens.Zoom
import Control.Lens.Internal.Zoom
data AwesomeState = AwesomeState
{ _someRecord :: String
-- ...
}
$(makeLenses ''AwesomeState)
newtype Awesome s a = Awesome (StateT s (ErrorT String IO) a)
deriving ( Functor, Applicative, Monad
, MonadIO, MonadError String
, MonadState s)
然后你可以为它定义Zoom
实例如下:
type instance Zoomed (Awesome s) = Focusing (ErrorT String IO)
instance Zoom (Awesome s) (Awesome t) s t where
zoom l (Awesome m) = Awesome (zoom l m)
那么你将拥有
zoom someRecord :: Awesome String a -> Awesome AwesomeState a
我有兴趣为我的 monad 转换器堆栈获取 缩放 功能,该功能按以下方式定义:
newtype Awesome a = Awesome (StateT AwesomeState (ExceptT B.ByteString IO) a)
deriving (Functor, Applicative, Monad
, MonadIO, MonadError B.ByteString
, MonadState AwesomeState)
我的 AwesomeState 是深度嵌套的记录,所以使用缩放对我更新一些字段有很大帮助。但问题是缩放对于我的新类型来说不是开箱即用的。
Couldn't match type ‘Control.Lens.Internal.Zoom.Zoomed Awesome’
with ‘Control.Lens.Internal.Zoom.Zoomed m0’
我找到了一个示例,说明如何制作 Zoom 的自定义新类型 RWST 实例,但尝试使其适应我的新类型却没有结果
可以在此处找到 RWST 示例:http://lpaste.net/87737
有什么方法可以让我开始使用我的 monad 转换器堆栈进行缩放吗?为了实现这一目标,我需要做什么?如果我应该像 RWST 示例中那样实现 Zoomed/Zoom,那么我需要一个关于如何实现的指针,因为我尝试过但失败了。
我建议明确 Awesome
的状态:
{-# LANGUAGE TemplateHaskell, GeneralizedNewtypeDeriving, TypeFamilies,
FlexibleInstances, FunctionalDependencies #-}
import Control.Applicative
import Control.Monad.Error
import Control.Monad.State
import Control.Lens
import Control.Lens.Zoom
import Control.Lens.Internal.Zoom
data AwesomeState = AwesomeState
{ _someRecord :: String
-- ...
}
$(makeLenses ''AwesomeState)
newtype Awesome s a = Awesome (StateT s (ErrorT String IO) a)
deriving ( Functor, Applicative, Monad
, MonadIO, MonadError String
, MonadState s)
然后你可以为它定义Zoom
实例如下:
type instance Zoomed (Awesome s) = Focusing (ErrorT String IO)
instance Zoom (Awesome s) (Awesome t) s t where
zoom l (Awesome m) = Awesome (zoom l m)
那么你将拥有
zoom someRecord :: Awesome String a -> Awesome AwesomeState a