- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试了解有关镜头库的更多信息。我已经了解 lens-family 中的镜头包及其派生,也掌握了Store、Pretext 和Bazaar 的两个类型参数版本,但我在理解时遇到了麻烦Control.Lens.Traversal
的 partsOf
, holesOf
和 singular
函数,定义了复杂的类型和许多辅助函数。这些函数是否也可以用更简单的方式来表达以进行学习?
最佳答案
这是一个相当大而棘手的问题。我承认我自己并不完全了解如何holesOf
和 partsOf
工作,我不明白如何singular
直到几分钟前才工作,但我想写下一个可能对您有帮助的答案。
我想解决一个更普遍的问题:如何阅读 lens
源代码。因为如果你记住几个简化的假设,你通常可以简化疯狂的定义,比如
singular :: (Conjoined p, Functor f)
=> Traversing p f s t a a
-> Over p f s t a a
singular l = conjoined
(\afb s -> let b = l sell s in case ins b of
(w:ws) -> unsafeOuts b . (:ws) <$> afb w
[] -> unsafeOuts b . return <$> afb (error "singular: empty traversal"))
(\pafb s -> let b = l sell s in case pins b of
(w:ws) -> unsafeOuts b . (:Prelude.map extract ws) <$> cosieve pafb w
[] -> unsafeOuts b . return <$> cosieve pafb (error "singular: empty traversal"))
unsafeOuts :: (Bizarre p w, Corepresentable p) => w a b t -> [b] -> t
unsafeOuts = evalState `rmap` bazaar (cotabulate (\_ -> state (unconsWithDefault fakeVal)))
where fakeVal = error "unsafePartsOf': not enough elements were supplied"
ins :: Bizarre (->) w => w a b t -> [a]
ins = toListOf (getting bazaar)
unconsWithDefault :: a -> [a] -> (a,[a])
unconsWithDefault d [] = (d,[])
unconsWithDefault _ (x:xs) = (x,xs)
lens
时尝试应用的规则。源代码:
s-t-a-b
整个库中的表单,它允许您修改“目标”的类型(充其量是一个重载的词)。但是许多光学器件只需
s
即可实现和
a
,并且通常没有必要跟踪
t
s 和
b
s 当您只是想阅读定义时。
singular
,我在我的临时文件中使用了这些类型:
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE NoImplicitPrelude #-}
import BasePrelude hiding (fold)
type Lens big small =
forall f. (Functor f) => (small -> f small) -> (big -> f big)
type Traversal big small =
forall ap. (Applicative ap) => (small -> ap small) -> (big -> ap big)
makeLens :: (big -> small) -> (big -> small -> big) -> Lens big small
makeLens getter setter =
\liftSmall big -> setter big <$> liftSmall (getter big)
set :: ((small -> Identity small) -> big -> Identity big) -> small -> big -> big
set setter new big =
runIdentity (setter (\_ -> Identity new) big)
view :: ((small -> Const small small) -> big -> Const small big) -> big -> small
view getter big =
getConst (getter Const big)
lens
开发者使用
profunctors (例如
Choice
和
Conjoined
)及其伴随的辅助函数(
dimap
,
rmap
)。
lens
代码我发现几乎总是假设
p ~ (->)
很有帮助(函数类型)每当我看到一个 profunctor 变量。这让我可以删除
Representable
,
Conjoined
,
Bizarre
, 和
Over
来自上述代码片段中签名的类型类。
singular
在我们更简单、更笨的类型之上。
singular :: Traversal big small -> Lens big small
singular = _
big
使用
[small]
获取小列表(
Const
)的值然后把它们放回我们使用
State
得到的地方.
toListOf
来完成。 :
toListOf :: Traversal big small -> big -> [small]
toListOf traversal = foldrOf traversal (:) []
-- | foldMapOf with mappend/mzero inlined
foldrOf :: Traversal big small -> (small -> r -> r) -> r -> big -> r
foldrOf traversal fold zero =
\big -> appEndo (foldMapOf traversal (Endo . fold) big) zero
-- | Traverses a value of type big, accumulating the result in monoid mon
foldMapOf :: Monoid mon => Traversal big small -> (small -> mon) -> big -> mon
foldMapOf traversal fold =
getConst . traversal (Const . fold)
Endo
的列表来自
Const
s。
singular :: Traversal big small -> Lens big small
singular traversal liftSmall big = do
case toListOf traversal big of
(x:xs) -> _
[] -> _
unsafeOuts :: (Bizarre p w, Corepresentable p) => w a b t -> [b] -> t
unsafeOuts = evalState `rmap` bazaar (cotabulate (\_ -> state (unconsWithDefault fakeVal)))
where fakeVal = error "unsafePartsOf': not enough elements were supplied"
newtype Bazaar' small small' big =
Bazaar { unBazaar :: forall ap. Applicative ap => (small -> ap small') -> ap big }
deriving Functor
instance Applicative (Bazaar' small small') where
pure big =
Bazaar (\_ -> pure big)
Bazaar lhs <*> Bazaar rhs =
Bazaar (\liftSmall -> lhs liftSmall <*> rhs liftSmall)
type Bazaar small big = Bazaar' small small big
gobble :: StateT Identity [a] a
gobble = state (unconsWithDefault (error "empty!"))
unsafeOuts :: Bazaar small big -> [small] -> big
unsafeOuts (Bazaar bazaar) smalls =
evalState (bazaar (\_ -> gobble)) smalls
rmap = (.)
和
cotabulate f = f . Identity
,我们能够这样做是因为我们假设了
p ~ (->)
.
lens
文档提到它就像一个已经应用于结构的遍历。如果您乘坐
Traversal
,确实会得到一个集市。键入并将其应用于
big
你已经拥有的值(value)。
FunList
datatype ,用户 Zemyla 计算出之间的等价关系
data FunList a b t
= Done t
| More a (FunList a b (b -> t))
instance Functor (FunList a b) where ...
instance Applicative (FunList a b) where ...
instance Profunctor (FunList a) where ...
-- example values:
-- * Done (x :: t)
-- * More (a1 :: a) (Done (x :: a -> t))
-- * More (a1 :: a) (More (a2 :: a) (Done (x :: a -> a -> t))
lens
市场。我发现这种表示对于直观了解正在发生的事情更有帮助。
gobble
,每次运行时都会从状态中弹出列表的头部。我们的
bazaar
可以升级
gobble :: StateT Identity [small] small
值变成
bazaar (\_ -> gobble) :: StateT Identity [small] big
.与遍历非常相似,我们能够对小值的一部分采取有效的行动,并将其升级为对整个值起作用的行动。这一切都发生得很快,而且代码似乎不够;它有点让我头晕目眩。
bazaarOf :: Traversal big small -> big -> Bazaar small big
bazaarOf traversal =
traversal (\small -> Bazaar (\liftSmall -> liftSmall small))
-- See below for `ix`.
λ> unBazaar (bazaarOf (ix 3) [1,2,3,4]) Right
Right [1,2,3,4]
λ> unBazaar (bazaarOf (ix 3) [1,2,3,4]) (\_ -> Right 10)
Right [1,2,3,100]
λ> unBazaar (bazaarOf (ix 1) [1,2,3,4]) Left
Left 2
traverse
的“延迟”版本。 .)
unsafeOuts
给了我们一种方法来检索第二个
big
给定列表的值
small
值(value)观和从第一个
big
构建的集市值(value)。现在我们需要根据传入的原始遍历构建一个集市:
singular :: Traversal big small -> Lens big small
singular traversal liftSmall big = do
let bazaar = traversal (\small -> Bazaar ($ small)) big
case toListOf traversal big of
(x:xs) -> _
[] -> _
Bazaar small small
.由于我们计划遍历 big
,我们可以拿每个x :: small
我们得到并构造一个 Bazaar (\f -> f x) :: Bazaar small small
的值.这就够了! Bazaar small small
成bazaar :: Bazaar small big
. lens
代码使用
b = traversal sell big
执行此操作, 使用
sell
来自
Sellable (->) (Bazaar (->))
实例。如果您内联该定义,您应该最终得到相同的结果。
x:xs
案例
x
是我们想要采取行动的值(value)。它是我们给定的遍历目标的第一个值,现在它成为我们返回的镜头的第一个目标值。我们调用
liftSmall x
获得
f small
对于一些仿函数
f
;然后我们附加
xs
在仿函数里面得到一个
f [small]
;然后我们打电话
unsafeOuts bazaar
在仿函数里面转
f [small]
回到
f big
:
singular :: Traversal big small -> Lens big small
singular traversal liftSmall big = do
let bazaar = traversal (\small -> Bazaar ($ small)) big
case toListOf traversal big of
(x:xs) -> fmap (\y -> unsafeOuts bazaar (y:xs)) <$> liftSmall x
[] -> _
singular :: Traversal big small -> Lens big small
singular traversal liftSmall big = do
let bazaar = traversal (\small -> Bazaar ($ small)) big
case toListOf traversal big of
(x:xs) -> fmap (\y -> unsafeOuts bazaar (y:xs)) <$> liftSmall x
[] -> fmap (\y -> unsafeOuts bazaar [y]) <$> liftSmall (error "singularity")
-- | Constructs a Traversal that targets zero or one
makePrism :: (small -> big) -> (big -> Either big small) -> Traversal big small
makePrism constructor getter =
\liftSmall big -> case (fmap liftSmall . getter) big of
Left big' -> pure big'
Right fsmall -> fmap constructor fsmall
_Cons :: Traversal [a] (a, [a])
_Cons = makePrism (uncurry (:)) (\case (x:xs) -> Right (x, xs); [] -> Left [])
_1 :: Lens (a, b) a
_1 = makeLens fst (\(_, b) a' -> (a', b))
_head :: Traversal [a] a
_head = _Cons . _1
ix :: Int -> Traversal [a] a
ix k liftSmall big =
if k < 0 then pure big else go big k
where
go [] _ = pure []
go (x:xs) 0 = (:xs) <$> liftSmall x
go (x:xs) i = (x:) <$> go xs (i - 1)
lens
偷来的图书馆。
Monoid
类型类离开:
λ> :t view _head
view _head :: Monoid a => [a] -> a
λ> :t view (singular _head)
view (singular _head) :: [small] -> small
λ> view _head [1,2,3,4]
[snip]
• Ambiguous type variable ‘a0’ arising from a use of ‘print’
prevents the constraint ‘(Show a0)’ from being solved.
[snip]
λ> view (singular _head) [1,2,3,4]
1
λ> set (ix 100) 50 [1,2,3]
[1,2,3]
λ> set (singular (ix 100)) 50 [1,2,3]
[1,2,3]
λ> set _head 50 [1,2,3,4]
[50,2,3,4]
λ> set (singular _head) 50 [1,2,3,4]
[50,2,3,4]
partsOf
和
holesOf
-- | A type-restricted version of 'partsOf' that can only be used with a 'Traversal'.
partsOf' :: ATraversal s t a a -> Lens s t [a] [a]
partsOf' l f s = outs b <$> f (ins b) where b = l sell s
partsOf
与
singular
极其相似因为它首先构建了一个集市
b
, 调用
f (ins b)
在集市上,然后“将值(value)放回它找到的地方”。
holesOf :: forall p s t a. Conjoined p => Over p (Bazaar p a a) s t a a -> s -> [Pretext p a a t]
holesOf l s = unTagged
( conjoined
(Tagged $ let
f [] _ = []
f (x:xs) g = Pretext (\xfy -> g . (:xs) <$> xfy x) : f xs (g . (x:))
in f (ins b) (unsafeOuts b))
(Tagged $ let
f [] _ = []
f (wx:xs) g = Pretext (\wxfy -> g . (:Prelude.map extract xs) <$> cosieve wxfy wx) : f xs (g . (extract wx:))
in f (pins b) (unsafeOuts b))
:: Tagged (p a b) [Pretext p a a t]
) where b = l sell s
holesOf
也在做集市(
l sell s
第三次!))并再次患上结膜炎:假设
p ~ (->)
您可以删除
conjoined
的第二个分支.但是接下来你会留下一堆
Pretext
s 和 comonads,我不完全确定它们是如何结合在一起的。值得进一步探索!
关于haskell - Control.Lens.Traversal 的partsOf、holesOf 和singular 的简单定义是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44310458/
给定 data Person = Person { _name :: String } makeClassy ''Person 它创建了一个 name :: Lens' Person String 我
Python内置的len()函数的成本是多少?(列表/元组/字符串/词典)
这个问题在这里已经有了答案: 9年前关闭。 Possible Duplicate: lenses, fclabels, data-accessor - which library for struct
Python 哪个性能更好: 1) for i in range(len(a[:-1])): foo() 或 2) for i in range(len(a)-1): foo() 更新
我正在学习 Python 并正在学习谷歌代码类(class)。在 list2.py 示例中,他们要求我们编写一个函数: Given two lists sorted in increasing ord
我最近开始使用 Python 进行数据分析,由于我不是从头开始学习 Python,所以我觉得我错过了一些细微差别。 我注意到的一件事是,在我的一份报告中,我从 CSV 文件中导入了一个数据集,将其作为
为什么a[len(a):] = [x]等同于a.append(x),但是a[len(a) ] = [x] 给出超出范围的错误? 最佳答案 根据 the documentation (强调我的): If
当我运行以下宏时: Sub try() Dim num As Integer num = 123 MsgBox Len(num) MsgBox VBA.Len(num)
我目前正在获取 Python 3.x 中以 0 的随机长度结尾的随机数列表。例如,我得到以下一组随机数字字符串: String 1 = 203502000000 String 2 = 30293300
我正在学习 numba 并遇到了这种我不理解的“奇怪”行为。我尝试使用以下代码(在 iPython 中,用于计时): import numpy as np import numba as nb @nb
在Go , 要检查字符串是否为空,可以使用: len(str) == 0 或 len(str) < 1 或 str == "" 基本上就是选择运营商的一米== , < , != ,但就性能而言希望选项
我正在尝试创建一个函数 hpure通过重复相同的元素直到达到所需的长度来生成 hvect。每个元素可能有不同的类型。例如:如果参数是 show 每个元素将是 show 函数的特化。 hpure sho
我正在实现一个图形操作脚本,但我对以下错误感到困惑: Traceback (most recent call last): File ".....py", line 12, in pri
通常为了节省一些时间,我希望我们在本地函数中使用 n = len(s)。我很好奇哪个调用更快或者它们相同? while i < len(s): # do something 对比 while i
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
大家好! 我从这个网站找到了这段很棒的代码: var points = [30,100]; document.getElementById("demo").innerHTML = myArrayMax
我有一个输出 17 个维度的解码器,其中不同部分是标签和数字。因此,对于标签,我使用了 one-hot 编码并使用“softmax”激活,对于数字,我使用了“sigmoid”激活函数。 这是解码器:
我在下面得到了这段代码,但即使调试它,我也不明白为什么给出 7 而不是 6。 更准确地说,当我调试每个返回时都会给我预期的结果: 第一个函数调用:ipdb> --Return-- ['a'] 第二个函
上述分配可能会出现什么样的问题?如果我们分配实际数据类型的大小而不是该类型指针的大小? 对于 sizeof (char*) > sizeof (char) 的字符来说,这会是一个问题吗?其他数据类型和
我知道 somelist[len(somelist)] 无法访问定义列表之外的索引 - 这是有道理的。 但是为什么 Python 允许你做 somelist[len(somelist):]? 我什至读
我是一名优秀的程序员,十分优秀!