> {-# LANGUAGE DeriveFunctor, Rank2Types, ExistentialQuantification #-}
任何归纳类型都是这样定义的
> newtype Ind f = Ind {flipinduct :: forall r. (f r -> r) -> r}
> induction = flip flipinduct
归纳
具有类型(f a->a)->Ind f->a
。对此有一个双重概念,叫做共感应。
> data CoInd f = forall r. Coinduction (r -> f r) r
> coinduction = Coinduction
共感应
具有(a->f a)->a->CoInd f
类型。注意归纳
和共归纳
是如何对偶的。作为归纳和共归纳数据类型的示例,请看这个函式。
> data StringF rec = Nil | Cons Char rec deriving Functor
> wrap :: (Functor f) => f (CoInd f) -> CoInd f
> wrap fc = coinduction igo Nothing where
> --igo :: Maybe (CoInd f) -> f (Maybe (CoInd f))
> igo Nothing = fmap Just fc
> igo (Just (Coinduction step seed)) = fmap (Just . Coinduction step) $ step seed
> convert :: (Functor f) => Ind f -> CoInd f
> convert = induction wrap
> cowrap :: (Functor f) => Ind f -> f (Ind f)
> cowrap = induction igo where
> --igo :: f (f (Ind f)) -> f (Ind f)
> igo = fmap (\fInd -> Ind $ \fold -> fold $ fmap (`flipinduct` fold) fInd)
归纳
总是O(n)
,cowrap
也是如此。
我们可以使用cointension
从cowrap
和ind f
生成coind f
。
> convert' :: (Functor f) => Ind f -> CoInd f
> convert' = coinduction cowrap
这也是每次我们获得一个元素时O(n)
,总共O(n^2)
。
我的问题是,如果不使用递归(直接或间接),我们能否在O(n)
时间内将ind f
转换为coind f
?
我知道如何使用递归(将ind f
转换为fix f
,然后将fix f
转换为O(n)
(初始转换是O(n)
,但随后coind f
)中的每个元素都是O(1)
,使得第二次转换O(n)
total和O(n)+O(n)=O(n)
),但我想看看是否可以不这样做。
注意convert
和convert'
从未直接或间接地使用递归。很漂亮,不是吗!
是的,这在形式上是可能的:
https://github.com/jyp/controlledfusion/blob/master/control/fixpoints.hs
但是,转换仍然需要在运行时构造中间缓冲区,这只能使用循环来完成。
HList是共感的吗?如果是,一个共感类型如何包含有限值? 如果我们定义呢?这会被认为是什么和/或它会比有用吗?
问题内容: 我是Go编程语言的新手,我有一个创建和解释器的任务,但是我遇到了以下问题: 我想将环境定义为: 但是我收到错误“无效的递归类型环境”。根据我的研究,我将父级更改为 Environment。但是现在,当我需要创建一个环境类型为var的新环境时,它会收到错误消息“无法将fun_Val.ds(环境类型)用作 环境值类型”。我正在如下创建环境: 我试图将这篇文章中的代码量限制在一定范围内,但是
我有一个关于如何将“递归”转换为“尾部递归”的问题。 这不是家庭作业,只是在我试图润色算法书籍中的递归定理时出现的一个问题。 我熟悉使用递归的两个典型示例(阶乘和斐波那契序列),也知道如何以递归方式和尾部递归方式实现它们。 我的代码如下(我使用Perl只是为了使其简单,但可以轻松地转换为C/Java/C)。 运行代码时,输出如下: 递归函数在返回之前使用不同的参数调用自己两次。我尝试了几种方法将其
计算机的威力源自其反复执行同一任务或同一任务不同版本的能力。在计算领域,迭代这一主题会以多种形式出现。数据模型中的很多概念(比如表)都是某种形式的重复,比如“表要么为空,要么由一个元素接一个元素,再接一个元素,如此往复而成”。使用迭代,程序和算法可以在不需要单独指定大量相似步骤的情况下,执行重复性的任务,如“执行下一步骤1000次”。编程语言使用像C语言中的while语句和for语句那样的循环结构
问题 你有一个对象数组,想要把它们归纳为一个值,类似于 Ruby 中的 reduce() 和 reduceRight() 。 解决方案 可以使用一个匿名函数包含 Array 的 reduce() 和 reduceRight() 方法,保持代码清晰易懂。这里归纳可能会像对数值和字符串应用 + 运算符那么简单。 [1,2,3,4].reduce (x,y) -> x + y # => 10 ["wo
查看我在某处(这里是游乐场)找到的这个Typescript4.2片段: 我的头不能绕着它。TS如何处理这件事?它怎么不卡在无限递归里?具体地说,对于和的情况,悬停在变量上显示TS将类型解析为和。这是怎么回事?