Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何使用镜头实现不安全部分_Haskell_Haskell Lens - Fatal编程技术网

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
的第二个类型参数具有role
phantom
,因此这只是
强制
的一个专门化。
getter s = s ^.. (\f -> Const . getConst . traverse (Const . getConst . f))