Haskell 如何使用镜头实现不安全部分
我正在尝试使用专门的签名实现一个简单版本的Haskell 如何使用镜头实现不安全部分,haskell,haskell-lens,Haskell,Haskell Lens,我正在尝试使用专门的签名实现一个简单版本的unsafePartsOf: unsafePartsOf :: Traversal s t a b -> Lens s t [a] [b] 在试图理解它是如何工作的之后,我提出了这个() 我认为使用lens::(s->a)->(s->b->t)->lens stab来分离定义getter和setter将使它们更容易理解 但是,此函数不进行类型检查,因为^..运算符(toListOf)具有toListOf::Traversal's a->s->[a
unsafePartsOf
:
unsafePartsOf :: Traversal s t a b -> Lens s t [a] [b]
在试图理解它是如何工作的之后,我提出了这个()
我认为使用lens::(s->a)->(s->b->t)->lens stab
来分离定义getter和setter将使它们更容易理解
但是,此函数不进行类型检查,因为^..
运算符(toListOf
)具有toListOf::Traversal's a->s->[a]
的(专用)签名,其中原始的s
和t
(以及a
和b
)将得到统一
然后,我尝试用以下代码实现更通用的toListOf
():
toListOf :: Traversal s t a b -> s -> [a]
toListOf traverse s = execState (traverse getElem s) []
where getElem a = modify (a:)
但再次失败,因为由于使用了modify
,因此需要将b
与()
统一起来。我知道我无法在getElem
中创建任意的b
,因此此函数是不可能的
请注意,实际上可以使用镜头
以类似的方式定义安全部件
:
myPartsOf :: Traversal' s a -> Lens' s [a]
myPartsOf t = lens getter setter
where
getter s = s ^.. t
-- setter :: s -> [a] -> s
setter s xs = evalState (s & t %%~ assignElem) xs
assignElem a = state $ \case
[] -> (a, [])
(x : xs) -> (x, xs)
是否可以使用
lens
定义unsafePartsOf
?如果是这样,我该怎么做?您可以将getter定义为:
getter s = s ^.. (\f -> Const . getConst . traverse (Const . getConst . f))
而且它看起来像是在进行打字检查。这是一种通过用常量重新敲打来摆脱幻影b
统一的聪明方法!该模式的一个可爱的名称是recomb=Const。getConst
-它“重建”或“重建”包装器。当然,由于Const
的第二个类型参数具有rolephantom
,因此这只是强制
的一个专门化。
getter s = s ^.. (\f -> Const . getConst . traverse (Const . getConst . f))