- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试更深入地了解 lens
图书馆,所以我玩弄它提供的类型。我已经有一些使用镜头的经验,并且知道它们有多么强大和方便。所以我转向棱镜,我有点迷茫。棱镜似乎允许两件事:
^?
使用普通镜片可以得到
Nothing
如果有问题的字段不属于实体所代表的分支,就像它与棱镜一样。
最佳答案
镜头刻画了has-a关系;棱镜表征 is-a 关系。
一个 Lens s a
说“s
有一个 a
”;它有方法可以得到一个 a
来自 s
并准确覆盖一个 a
在 s
.一个 Prism s a
说“a
是 s
”;它具有向上转换 a
的方法到 s
并(试图)降低 s
到 a
.
将这种直觉放入代码中会为您提供熟悉的“get-set”(或“costate comonad coalgebra”)镜片公式,
data Lens s a = Lens {
get :: s -> a,
set :: a -> s -> s
}
以及棱镜的“向上向下”表示,
data Prism s a = Prism {
up :: a -> s,
down :: s -> Maybe a
}
up
注入(inject)
a
进入
s
(不添加任何信息)和
down
测试
s
是否是
a
.
lens
,
up
拼写为
review
和
down
是
preview
.没有
Prism
构造函数;您使用
the prism'
smart constructor .
Prism
做什么?注入(inject)和项目总和类型!
_Left :: Prism (Either a b) a
_Left = Prism {
up = Left,
down = either Just (const Nothing)
}
_Right :: Prism (Either a b) b
_Right = Prism {
up = Right,
down = either (const Nothing) Just
}
镜头不支持这个 - 你不能写
Lens (Either a b) a
因为你不能实现
get :: Either a b -> a
.作为一个实际问题,你可以写一个
Traversal (Either a b) a
,但这不允许您创建
Either a b
来自
a
- 它只会让你覆盖
a
已经在那里了。
Aside: I think this subtle point about
Traversal
s is the source of your confusion about partial record fields.
^?
with plain lenses allows gettingNothing
if the field in question doesn't belong to the branch the entity represents
使用^?
与真正的Lens
永远不会返回Nothing
, 因为一个Lens s a
准确识别一个a
在s
内.
遇到部分记录字段时,data Wibble = Wobble { _wobble :: Int } | Wubble { _wubble :: Bool }
makeLenses
将生成Traversal
,而不是Lens
.wobble :: Traversal' Wibble Int
wubble :: Traversal' Wibble Bool
例如Prism
s可以在实践中应用,看Control.Exception.Lens
,它提供了Prism
的集合s 到 Haskell 的可扩展Exception
等级制度。这使您可以在SomeException
上执行运行时类型测试。 s 并将特定异常注入(inject)SomeException
.(这些是实际类型的略微简化版本。实际上,这些棱镜是重载的类方法。)_ArithException :: Prism' SomeException ArithException
_AsyncException :: Prism' SomeException AsyncException
-- etc.
在更高的层次上思考,某些完整的程序可以被认为是“基本上是一个Prism
”。编码和解码数据就是一个例子:您总是可以将结构化数据转换为String
,但不是每个String
可以解析回来:总而言之,showRead :: (Show a, Read a) => Prism String a
showRead = Prism {
up = show,
down = listToMaybe . fmap fst . reads
}Lens
es 和Prism
s 一起编码了面向对象编程的两个核心设计工具:组合和子类型。Lens
es 是 Java 的.
的一流版本。和=
运算符和Prism
s 是 Java 的instanceof
的一流版本。和隐式向上转型。
一种富有成效的思考方式Lens
es 是它们为您提供了一种拆分组合s
的方法成为一个专注的值(value)a
和一些上下文c
.伪代码:在这个框架中,一个type Lens s a = exists c. s <-> (a, c)
Prism
为您提供查看s
的方法作为a
或某些上下文c
.(我会让你相信这些与我上面演示的简单表示同构。尝试为这些类型实现type Prism s a = exists c. s <-> Either a c
get
/set
/up
/down
!)
在这个意义上,Prism
是合作-Lens
.Either
是(,)
的分类对偶;Prism
是Lens
的分类对偶.
您还可以在 "profunctor optics" 中观察到这种二元性。配方 -Strong
和Choice
是双重的。这或多或少是type Lens s t a b = forall p. Strong p => p a b -> p s t
type Prism s t a b = forall p. Choice p => p a b -> p s tlens
的表示。使用,因为这些Lens
es 和Prism
s 是非常可组合的。您可以撰写Prism
s 变大Prism
s ("a
是s
, 这是p
") 使用(.)
;组成Prism
与Lens
给你一个Traversal
.
关于haskell - 什么是棱镜?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50915526/
假设我有一对转换函数 string2int :: String -> Maybe Int int2string :: Int -> String 我可以使用光学很容易地表示这些。 stringIntP
在使用镜头时,我偶尔需要在光学链中进行一些基本的文本解析。在我处理的一个 API 中,有一个像这样的 JSON 字段: "timespent": "0.25", 由于它被错误地编码为字符串而不是数字,
我开始学习 OpenGL 并将其与 SFML 2.1 一起使用以获取窗口、加载图像等。但是我遇到了简单棱镜的问题。面部部分透明,看起来很糟糕:/我正在看教程,但我不知道我的代码有什么问题......你
我正在使用 Unity 4.6 开发一个项目。我想知道是否有一种简单的方法来以编程方式设置顶点位置。目前我的代码看起来像这样 (C#): public void createPoints(float
我正在使用 Prism并且它适用于 CSS: p { color: red } 但我不能让它为 html 工作: red text 我有两个问题: 表示为标签,而不是文本,但我可以将其替换为 <
只需阅读精彩的“Lens/Aeson Traversals/Prisms" 文章并拥有一个实际应用程序。给定以下匿名 JSON 结构,我将如何棱镜出一个集合而不是特定值? {"Locations" :
我正在尝试在多对多表(引用自身)上使用 prisma 这样的一行将有子孙 我可以毫无问题地获取所有行,但我正在努力了解如何在可读的 JSON 中排序数据,这将阻止在前端进行解析 预期输出如下:返回的
我正在 Unity 中创建一个 2D sprite 游戏,这是一个 3D 游戏开发环境。我已将对象的所有平移限制在 XY 平面上,并将旋转限制在 Z 轴上。 我的问题是用于检测对象之间碰撞的网格必须仍
我正在尝试在多对多表(引用自身)上使用 prisma 这样的一行将有子孙 我可以毫无问题地获取所有行,但我正在努力了解如何在可读的 JSON 中排序数据,这将阻止在前端进行解析 预期输出如下:返回的
我有两个表 User 和 Post 由自定义的多对多表链接,例如: model User { id Int @id @default(autoincrement()
我有一个包含三个矩阵的列表a和一个具有三个高度(任何正实数)的向量h。这些矩阵形成三角形,即棱柱的底面。我想添加向量h的信息来构造棱镜。 我创建了一个以 2D 形式绘制图形的函数 (pplot)。如何
这个在跟我玩,我似乎无法弄明白 - 我需要一些外部帮助,兄弟们! 我想要一个没有标题、最小化、最大化和关闭按钮的弹出窗口,因为我们想自己设置样式并在弹出窗口的屏幕上添加自定义关闭按钮。 所以我通过这些
我正在扩展 Prism使用自定义语言,我想突出显示类型(int、float、bool)。 我想匹配不以点或 : 符号开头的字符串。 我已经尝试过单独使用正则表达式但无法使其工作,所以我可能必须使用 P
我是一名优秀的程序员,十分优秀!