- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在 Haskell 中玩一个玩具项目。我正在实现一些之前用其他语言构建的数据结构,以熟悉它们在 Haskell 中的构建方式。这不是我的第一个函数式语言,我已经在 OCaml 中构建了几个项目,例如方案解释器,但我认为我的 OCaml 经验影响了我解决这个问题的方式。知道我正在实现的数据结构是 PR-四叉树,这并不是非常重要,但对于上下文可能有用。
我想要做的是匹配并解构守卫内的类型,即 OCaml 的匹配语句。
data Waypoint = WayPoint {
lat :: Float,
lon :: Float,
radius :: Float,
speed :: Float,
accel :: Float
} deriving (Show)
data Region = Region {
x :: Float,
y :: Float,
width :: Float
} deriving (Show)
data PRQuadtree = WhiteNode Region
| BlackNode Region Waypoint
| GreyNode {
topLeft :: PRQuadtree,
topRight :: PRQuadtree,
botLeft :: PRQuadtree,
botRight :: PRQuadtree,
region :: Region
} deriving (Show)
getRegion node
| BlackNode(r, _) = r
| WhiteNode(r) = r
| GreyNode = region node
getRegion
函数是我特别遇到问题的函数。如果我想要做的事情不清楚:我想简单地提取参数的一个元素,但这取决于参数是代数数据类型的哪个成员。在 OCaml 中我可以这样做:
let getRegion node = match node with
| BlackNode(r, _) = r
| WhiteNode(r) = r
| GreyNode = region(node)
(或者非常类似的东西,我的 OCaml 现在有点生疏了)。
然而,在 Haskell 中,这似乎并未将 r
绑定(bind)到保护分支的 RHS 范围内。我尝试查找模式守卫,因为它们听起来与我想要做的类似,但我无法真正理解这里发生的事情。实际上,我只想获得从 = 的 LHS 到 equals 的 RHS 的绑定(bind)(取决于我们已经下降的守卫的哪个分支)。
完成我在这里想做的事情的惯用 Haskell 方法是什么?
最佳答案
可以通过如下方式实现:
getRegion :: PRQuadtree -> Region
getRegion (BlackNode r _) = r
getRegion (WhiteNode r) = r
getRegion GreyNode{region=r} = r
或者甚至是
getRegion :: PRQuadtree -> Region
getRegion x = case x of
BlackNode r _ -> r
WhiteNode r -> r
GreyNode{} -> region x
在 Haskell 中,在前面添加类型签名是非常惯用的。
另一个选项是将 region
字段也扩展到其他情况:
data PRQuadtree = WhiteNode { region :: Region }
| BlackNode { region :: Region , waypoint :: Waypoint }
| GreyNode {
topLeft :: PRQuadtree,
topRight :: PRQuadtree,
botLeft :: PRQuadtree,
botRight :: PRQuadtree,
region :: Region
} deriving (Show)
现在,region
将适用于所有 PRQuadtree
值。
Haskell 像 ML 在定义代数数据类型时那样使用 |
来分隔不同的构造函数,但不使用它来分隔 case
分支,而是遵循语法
case .. of { pat1 -> e1 ; pat2 -> e2 ; ... }
可以用缩进代替
case .. of
pat1 -> e1
pat2 -> e2
...
另请注意,不鼓励使用部分字段选择器:
data A = A1 { foo :: Int } | A2
上面,foo A2
类型检查但崩溃了。另一方面,当所有构造函数中都存在某个字段时,我们就不会面临这样的风险。
关于Guards 中的 Haskell 类型解构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34685523/
我在寻找有关 JavaScript 解构的信息,并在 Packt Publication 的视频系列中找到了视频“解构赋值”。在视频的一开始,我看到了以下代码: var [a, b] = [1,2,3
知识渊博的人可以帮助我理解 Scalaz 的工作原理吗?和 co.有效吗?我是 Scalaz 的新手,有点迷失在探索中。 我想做的是在 List 中累积错误,例如 (v0 v1) foldLeft
Haskell 中的模式匹配可以用这种方式解构数字吗: f (n + 1) = n 我期望 ex 的前身:f 6 = 5、f 5 = 4 等。 我在这里找到了这种模式匹配用法: https://wik
我有一个与此类似的文件: const COLORS = { PRIMARY_COLOR: 'red', SECONDARY_COLOR: 'green' }; const APP = {
作为对 SO 问题的回答,我构建了一个循环函数,并构建了我迄今为止最复杂的解构,这奇迹般地起作用了: (defn fib? [a b & [c & r]] (if (= c (+ a b))
我对破坏感到困惑。 我在其中使用了 React,我们这样做了 const [ books, setBooks ] = useState([{a:'v'}] 和 const {books} = useC
我确定这在某个地方得到了回答,但我缺乏制定搜索的词汇。 #include class Thing { public: int value; Thing(); virtual ~Thing()
如果我在 javascript 中有这样一个对象: let obj = {b: 3, c: 4, d: 6} 如果我解构它,我可以很容易地得到不同的部分,例如,如果我这样做,我可以得到 c 和 d:
这个问题在这里已经有了答案: One-liner to take some properties from object in ES 6 (11 个回答) 2年前关闭。 我似乎不记得如何写这个解构模式
我有一个函数可以查询我的数据库中最近的 X 个条目,它返回一个 map 向量,如下所示: [{:itemID "item1" :category "stuff" :price 5} {:itemI
根据所选语言,我需要销毁对象并获得所需的值。 我该怎么做才能不破坏整个对象? const translate = { "navMenu1": { "en": "Menu 1",
我试图理解这种 ES6 解构。有人可以解释这行代码将编译成什么吗? const { loading, route: { pageName = 'default' } = {} } = this.pro
我有一个程序,可以输出这样的一些条件(这是实际输出,它是伪代码): if ( first occurance of 'AB' -0.5 ) * (( number of products viewe
Serilog的@的目的是什么?句法? 如果我运行以下命令: var dummy = new { Foo = "Bar", Date = DateTime.Now }; Log.Information
JSON 编码的数组从 PHP 传递到 HTML 文档。目前还不清楚如何将该数组解构为 javascript 可用的片段。例如,考虑以下 HTML: {"foo":[{"id":1},{"id":3}
我正在 Chrome 的控制台选项卡中尝试使用以下代码进行 JavaScript 解构,这给了我未捕获的语法错误:标识符“a”已被声明异常 o = { a: "foo", b: 12, c: "bar
我有一个 JavaSCript 对象 person,其中包含 id、name、phone 和 地址属性。我想修改属性名称并将它们放入新对象 personData 中。这可以一步完成吗?: 第 1 步(
有没有办法从 WPF 中获取 Geometry 实例的内部结构? 我需要转换一串用户输入的几何数据,例如 M10,100 C10,300 300,-200 300,100 Z 用于分离几何命令(移动、
我的代码中有一个 promise : req.getValidationResult() .then(result => { let errors = resu
我正在为 Apollo Client 生成 Flow 类型,我目前有这个: type FetchModuleQuery = {| // Fetch single module module:
我是一名优秀的程序员,十分优秀!