我看了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?基本上,索引遍历如何工作?