- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以今晚我正在考虑图距离算法,并想出了这个当我开车时:
module GraphDistance where
import Data.Map
distance :: (Ord a) => a -> Map a [a] -> Map a Int
distance a m = m'
where m' = mapWithKey d m
d a' as = if a == a' then 0 else 1 + minimum (Prelude.map (m'!) as)
一开始,我还为自己感到相当自豪,因为它看起来很优雅。但后来我意识到这是行不通的 - corecursion 可能会卡住循环中。
我必须编写代码来说服自己:
ghci> distance 1 $ fromList [(0,[1]),(1,[0,2]),(2,[1,3]),(3,[2])]
fromList [(0,1),(1,0),(2,^CInterrupted.
但现在我想我已经想清楚了。
是否有常见错误和反模式的列表当处理我可以阅读的核心数据时,这样我就可以训练我的大脑进行核心递归思考?经验很好地训练了我通过非核心递归进行思考数据,但如果可以的话,我想从其他人的错误中吸取教训。
最佳答案
嗯,处理核心递归数据时实际上只有一个根本性错误,那就是不小心使用了递归!
Corecursion 意味着数据在某种意义上是增量生成的。您的图形距离函数在这里很有启发性,因为它似乎应该起作用,因此请考虑增量部分应该在哪里:起点是从节点到自身的距离 0,否则大于 1比它自己的近邻之间的最小距离。因此,我们期望每个距离值都是增量的,这意味着我们需要它们本身具有适当的核心递归性。
所讨论的递归是由于 (+)
和 minimum
的组合而发生的:当找到最小值时,1
总是小于 1 + n
,而不需要担心 n
是什么...但是没有办法比较 Int
而没有计算整个值。
简而言之,该算法期望能够仅根据需要比较 (1 +)
应用于 0
的次数;也就是说,它想要使用“零”和“后继”定义的惰性自然数。
看哪:
data Nat = Z | S Nat
natToInt :: Nat -> Int
natToInt Z = 0
natToInt (S n) = 1 + natToInt n
instance Show Nat where show = show . natToInt
instance Eq Nat where
Z == Z = True
(S n1) == (S n2) = n1 == n2
_ == _ = False
Z /= Z = False
(S n1) /= (S n2) = n1 /= n2
_ /= _ = True
instance Ord Nat where
compare Z Z = EQ
compare Z (S _) = LT
compare (S _) Z = GT
compare (S n1) (S n2) = compare n1 n2
然后在 GHCi 中:
> distance 1 $ fromList [(0,[1]),(1,[0,2]),(2,[1,3]),(3,[2])]
fromList [(0,1),(1,0),(2,1),(3,2)]
证明您的算法有效[0];你的实现是不正确的。
<小时/>现在,作为一个细微的变化,让我们将您的算法应用于不同的图表:
> distance 1 $ fromList [(0,[1]),(1,[0]),(2,[3]),(3,[2])]
...我们期望它做什么?节点 2 或 3 距节点 1 的距离是多少?
在 GHCi 中运行它有明显的结果:
fromList [(0,1),(1,0),(2,^CInterrupted.
尽管如此,算法在此图上运行正常。你能看出问题所在吗?为什么它卡在 GHCi 中?
<小时/>综上所述,你需要清楚地区分两种不能自由混合的形式:
这两种形式都可以以结构无关的方式进行转换(例如,map
适用于有限和无限列表)。 Codata 可以在 corecursive 算法的驱动下增量消耗;数据可以递归生成,受递归算法限制。
你不能做的是递归地使用codata(例如,向左折叠无限列表)或以递归方式生成核心数据(由于懒惰,在Haskell中很少见)。
[0]:实际上,它在某些输入上会失败(例如,一些断开连接的图表),但这是一个不同的问题。
关于Haskell:常见的核心递归谬误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6273762/
在 Haskell 中,类型声明使用双冒号,即 (::),如 not::Bool -> Bool。 但是在许多语法与 Haskell 类似的语言中,例如榆树、 Agda 、他们使用单个冒号(:)来声明
insertST :: StateDecoder -> SomeState -> Update SomeState SomeThing insertST stDecoder st = ... Stat
如果这个问题有点含糊,请提前道歉。这是一些周末白日梦的结果。 借助 Haskell 出色的类型系统,将数学(尤其是代数)结构表达为类型类是非常令人愉快的。我的意思是,看看 numeric-prelud
我有需要每 5 分钟执行一次的小程序。 目前,我有执行该任务的 shell 脚本,但我想通过 CLI 中的键为用户提供无需其他脚本即可运行它的能力。 实现这一目标的最佳方法是什么? 最佳答案 我想你会
RWH 面世已经有一段时间了(将近 3 年)。在在线跟踪这本书的渐进式写作之后,我渴望获得我的副本(我认为这是写书的最佳方式之一。)在所有相当学术性的论文中,作为一个 haskell 学生,读起来多么
一个经典的编程练习是用 Lisp/Scheme 编写一个 Lisp/Scheme 解释器。可以利用完整语言的力量来为该语言的子集生成解释器。 Haskell 有类似的练习吗?我想使用 Haskell
以下摘自' Learn You a Haskell ' 表示 f 在函数中用作“值的类型”。 这是什么意思?即“值的类型”是什么意思? Int 是“值的类型”,对吗?但是 Maybe 不是“值的类型”
现在我正在尝试创建一个基本函数,用于删除句子中的所有空格或逗号。 stringToIntList :: [Char] -> [Char] stringToIntList inpt = [ a | a
我是 Haskell 的新手,对模式匹配有疑问。这是代码的高度简化版本: data Value = MyBool Bool | MyInt Integer codeDuplicate1 :: Valu
如何解释这个表达式? :t (+) (+3) (*100) 自 和 具有相同的优先级并且是左结合的。我认为这与 ((+) (+3)) (*100) 相同.但是,我不知道它的作用。在 Learn
这怎么行 > (* 30) 4 120 但这不是 > * 30 40 error: parse error on input ‘*’ 最佳答案 (* 30) 是一个 section,它仍然将 * 视为
我想创建一个函数,删除满足第二个参数中给定谓词的第一个元素。像这样: removeFirst "abab" ( 'b') = "abab" removeFirst [1,2,3,4] even =
Context : def fib(n): if n aand returns a memoized version of the same function. The trick is t
我明白惰性求值是什么,它是如何工作的以及它有什么优势,但是你能解释一下 Haskell 中什么是严格求值吗?我似乎找不到太多关于它的信息,因为惰性评估是最著名的。 他们各自的优势是什么。什么时候真正使
digits :: Int -> [Int] digits n = reverse (x) where x | n digits 1234 = [3,1,2,4]
我在 F# 中有以下代码(来自一本书) open System.Collections.Generic type Table = abstract Item : 'T -> 'U with ge
我对 Haskell 比较陌生,过去几周一直在尝试学习它,但一直停留在过滤器和谓词上,我希望能得到帮助以帮助理解。 我遇到了一个问题,我有一个元组列表。每个元组包含一个 (songName, song
我是 haskell 的初学者,我试图为埃拉托色尼筛法定义一个简单的函数,但它说错误: • Couldn't match expected type ‘Bool -> Bool’
我是 Haskell 语言的新手,我在使用 read 函数时遇到了一些问题。准确地说,我的理解是: read "8.2" + 3.8 应该返回 12.0,因为我们希望返回与第二个成员相同的类型。我真正
当我尝试使用真实项目来驱动它来学习 Haskell 时,我遇到了以下定义。我不明白每个参数前面的感叹号是什么意思,我的书上好像也没有提到。 data MidiMessage = MidiMessage
我是一名优秀的程序员,十分优秀!