5
我看着西蒙佩頓瓊斯談Control.Lens,他表明,鏡頭和LensR這裏定義的是同構:Control.Lens:穿越同構到toListOf及以上
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
}
我想與遍歷相同:
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
這裏,魔法:: A - > B,但我不能讓一般的功能(A - > B)。相反,我可以通過做一個部分函數來作弊:我知道函數應該返回什麼類型的可以遍歷的值。所以我可以從as和bs中創建一個關聯列表,然後從中創建一個部分函數。
這是行不通的?如果是這樣,請告訴我有更好的辦法!
或者我選擇了TraversableR的錯誤形式,而實際上沒有同構?
感謝您的任何建議。
編輯:
所以感謝安德拉斯·科瓦克斯我現在認爲,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?基本上,索引遍歷如何工作?
'TraversalR'似乎不好。使用'Traversal',你可以做有狀態的遍歷和e。 G。用每個'a'的位置索引替換。用'(a - > b) - > s - > t',這是不可能的。 –
噢好 - 我沒有意識到。 TraversalR應該是什麼樣子?你認爲呢? – RhubarbAndC
'overR :: [b] - > s - > t'會使'TraversalR'與['biplate']非常相似(https://hackage.haskell.org/package/uniplate-1.6.12/docs/Data -Generics-Uniplate-Operations.html#t:Biplate),所以這可能值得一試。 –