当前位置:  开发笔记 > 编程语言 > 正文

Control.Lens:toListOf及以上的遍历同构

如何解决《Control.Lens:toListOf及以上的遍历同构》经验,为你挑选了0个好方法。

我看了Simon Peyton Jones关于Control.Lens的讨论,他表明这里定义的Lens和LensR是同构的:

type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t

data LensR s t a b = LensR { 
    viewR :: s -> a,
    setR  :: b -> s -> t
}

我正试图对Traversal做同样的事情:

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t

data TraversalR s t a b = TraversalR {
    toListOfR :: s -> [a],
    overR :: (a -> b) -> s -> t
}

newtype CL a b = CL { getCL :: [a] }  -- ConstantList

instance Functor (CL a) where
  fmap _ (CL xs) = CL xs

instance Applicative (CL a) where
  pure _ = CL []
  (CL xs) <*> (CL ys) = CL (xs ++ ys)


travToTravR :: Traversal s t a b -> TraversalR s t a b
travToTravR tr = TraversalR {
    toListOfR = getCL . tr (CL . pure),
    overR = \f -> runIdentity . tr (Identity . f)
}

但我坚持使用travRToTrav.这是我能想到的最好的:

travRToTrav :: TraversalR s t a b -> Traversal s t a b
travRToTrav trR a2fb s = (\bs-> overR trR magic s) <$> f_bs
  where as = toListOfR trR s
        f_bs = sequenceA . map a2fb $ as
        magic = undefined

这里,magic :: a - > b,但我不能做一般功能(a - > b).相反,我可以通过创建一个部分函数来作弊:我知道函数应该返回任何可遍历的类型a的值.所以我可以从as和bs创建一个关联列表,然后从中创建一个部分函数.

这有用吗?如果是这样,请告诉我有更好的方法!

或者我为TraversableR选择了错误的表单,并且实际上没有同构?

谢谢你的建议.


编辑:

所以感谢AndrásKovács,我现在认为TraversalR应该是这样的:

data TraversalR s t a b = TraversalR {
  toListOfR :: s -> [a],
  setListR  :: [b] -> s -> t
}

然后travRToTrav与lensRToLens非常相似:

travRToTrav :: TraversalR s t a b -> Traversal s t a b
travRToTrav trR a2fb s = (`setL` s) <$> f_bs
   where as = toListOfR trR s
         f_bs = sequenceA . map a2fb $ as
         setL = setListR trR

但是,如何在travToTravR中定义setListR?基本上,索引遍历如何工作?

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有