Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
列表在Haskell中是归纳的还是共归纳的?_Haskell_Infinite_Idris_Induction_Coinduction - Fatal编程技术网

列表在Haskell中是归纳的还是共归纳的?

列表在Haskell中是归纳的还是共归纳的?,haskell,infinite,idris,induction,coinduction,Haskell,Infinite,Idris,Induction,Coinduction,所以我最近读了一些关于共导的书,现在我想知道:哈斯克尔列表是归纳的还是共导的?我还听说Haskell没有区分这两者,但如果是这样,他们是如何正式区分的 列表是以归纳方式定义的,data[a]=[]|a:[a],但也可以同时使用,ones=a:ones。我们可以创建无限的列表。然而,我们可以创建有限的列表。那么它们是什么 在Idris中,类型列表a严格来说是归纳类型,因此仅为有限列表。它的定义类似于Haskell中的定义。然而,streama是一种共导类型,为无限列表建模。它被定义为(或者更确切地

所以我最近读了一些关于共导的书,现在我想知道:哈斯克尔列表是归纳的还是共导的?我还听说Haskell没有区分这两者,但如果是这样,他们是如何正式区分的

列表是以归纳方式定义的,
data[a]=[]|a:[a]
,但也可以同时使用,
ones=a:ones
。我们可以创建无限的列表。然而,我们可以创建有限的列表。那么它们是什么

在Idris中,类型
列表a
严格来说是归纳类型,因此仅为有限列表。它的定义类似于Haskell中的定义。然而,
streama
是一种共导类型,为无限列表建模。它被定义为(或者更确切地说,该定义相当于)
codatastreama=a::(streama)
。创建无限列表或有限流是不可能的。然而,当我写下定义时

codata HList : Type -> Type where
    Nil : HList a
    Cons : a -> HList a -> HList a
我从Haskell列表中得到了我所期望的行为,即我可以生成有限和无限结构

让我把它们归结为几个核心问题:

  • 哈斯克尔没有区分归纳型和共归纳型吗?如果是这样的话,它的形式化是什么?如果不是,那么哪个是[a]

  • HList是共导的吗?如果是这样,共导类型如何包含有限值

  • 如果我们定义了
    数据HList'a=L(列表a)| R(流a)
    ,会怎么样?这会被认为是什么和/或仅在
    HList
    上有用吗

  • 由于懒惰,Haskell类型是归纳型和共归纳型的,或者,在数据和codata之间没有正式的区别。所有递归类型都可以包含构造函数的无限嵌套。在Idris、Coq、Agda等语言中,终止检查器会拒绝类似于
    ones=1:ones
    的定义。懒惰意味着
    ones
    可以一步计算为
    1:ones
    ,而其他语言只计算为标准形式,而
    ones
    没有标准形式

  • “共导”并不意味着“必然无限”,它意味着“由解构的方式定义”,而归纳意味着“由构造的方式定义”。我认为这是对细微差别的极好解释。你肯定会同意

    codata A:Type,其中MkA:A

    不可能是无限的

  • 这是一个有趣的问题-与
    HList
    相反,你永远无法“知道”它是有限的还是无限的(特别是,你可以在有限的时间内发现一个列表是有限的,但你无法计算它是无限的),
    HList'
    提供了一种简单的方法,可以在固定时间内确定列表是有限的还是无限的


  • 在Coq或Agda这样的总体语言中,归纳类型是那些其值可以在有限时间内被删除的类型。感应功能必须终止。另一方面,共导类型的值可以在有限的时间内建立。共导函数必须是有生产力的

    打算用作证明助手的系统(如Coq和Agda)必须是完整的,因为不终止会导致系统在逻辑上不一致。但要求所有函数都是完全的和归纳的,这使得它不可能与无限结构一起工作,因此,共归纳被发明了

    所以归纳和共归纳类型的目的是拒绝可能的非终止程序。以下是Agda中的一个函数示例,该函数因生产率条件而被拒绝。(传递给
    过滤器的函数可能会拒绝每个元素,因此您可能会永远等待结果流的下一个元素。)


    现在,Haskell没有归纳或共归纳类型的概念。“这种类型是归纳的还是共归纳的?”这个问题不是一个有意义的问题。哈斯凯尔怎么能不加区分就逃之夭夭呢?哈斯凯尔从一开始就不打算保持逻辑上的一致性。它是一种局部语言,这意味着您可以编写非终止和非生产性函数-没有终止检查器和生产性检查器。人们可以对这种设计决策的明智性进行辩论,但它肯定会使归纳和归纳变得多余


    相反,Haskell程序员习惯于非正式地推理程序的终止/生产率。懒惰让我们可以处理无限的数据结构,但我们不能从机器上得到任何帮助来确保我们的函数是完整的。

    要解释类型级递归,需要为 CPO值列表函子

    F X = (1 + A_bot * X)_bot
    
    如果我们归纳推理,我们希望不动点是“最小的”。如果是共生产的,“最大的”

    从技术上讲,这是通过在CPO_机器人的嵌入投影子类别中工作来实现的,例如,将嵌入图的共线取为“最小”

    0_bot |-> F 0_bot |-> F (F 0_bot) |-> ...
    
    推广Kleene不动点定理。对于“最大的”,我们将采用投影图的极限

    0_bot <-| F 0_bot <-| F (F 0_bot) <-| ...
    
    将有限列表集作为bilimit(直到iso)


    [我希望我的提升操作是正确的——这些操作很棘手;-)

    Haskell没有归纳或共归纳类型的概念。(因为它是一种不完整且懒惰的语言,所以它并不真正需要一个。)因此,询问给定的Haskell类型是归纳型还是共归纳型是没有意义的。您的
    HList
    类型通常被称为co-list。在Agda中,是否可以定义类似于HList的结构?在这种情况下,是否仍然施加生产力约束(就像codata一样),因此过滤器仍然无效?也就是说,Nil的引入并不影响它的有效性?没错。共导列表仍然可以是无限的(尽管与流不同,它们可能不是无限的),因此,
    过滤器
    仍然会被拒绝,因为它不会对所有输入都有效。请解释Haskell如何同时具有这两种类型?我很肯定
    0_bot <-| F 0_bot <-| F (F 0_bot) <-| ...
    
    F X = 1_bot # (A_bot x X)