Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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

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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.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
List 在哈斯克尔,为什么不是';对于可以像列表一样工作的事物,没有类型类吗?_List_Haskell_Typeclass - Fatal编程技术网

List 在哈斯克尔,为什么不是';对于可以像列表一样工作的事物,没有类型类吗?

List 在哈斯克尔,为什么不是';对于可以像列表一样工作的事物,没有类型类吗?,list,haskell,typeclass,List,Haskell,Typeclass,我正在阅读,我想知道为什么这么多事情都像一个列表,而前奏曲中没有使用类型类的本机功能来设置: :的bytestring版本称为cons,它接受一个字节和一个bytestring,并将字节放在开头。但它是惰性的,因此即使bytestring中的第一个块未满,它也会生成一个新块。这就是为什么最好使用cons的严格版本,如果要在bytestring的开头插入大量字节,那么最好使用cons的严格版本。” 为什么没有一个TypeClass listable或者提供了:函数来统一数据。ByteString,

我正在阅读,我想知道为什么这么多事情都像一个列表,而前奏曲中没有使用类型类的本机功能来设置:

:的bytestring版本称为cons,它接受一个字节和一个bytestring,并将字节放在开头。但它是惰性的,因此即使bytestring中的第一个块未满,它也会生成一个新块。这就是为什么最好使用cons的严格版本,如果要在bytestring的开头插入大量字节,那么最好使用cons的严格版本。”

为什么没有一个TypeClass listable或者提供了
函数来统一
数据。ByteString
数据。List
数据。ByteString。Lazy
,等等?这有什么原因吗,或者这仅仅是遗留Haskell的一个元素?使用
作为一个例子是一种轻描淡写,同样来自LYAH:

否则,bytestring模块具有一系列类似于Data.List中的函数,包括但不限于head、tail、init、null、length、map、reverse、foldl、foldr、concat、takeWhile、filter等

它提供了:统一Data.ByteString、Data.List、Data.ByteString.Lazy等的函数

有人试图设计出一个好的a)序列接口和b)容器接口,但是,统一不同类型、具有不同类型约束的数据类型,通常会使结果不够标准,很难想象将它们放在基本库中。同样,对于数组,尽管现在使用向量包具有相当通用的接口(基于关联的数据类型)

有几个项目可以用一个接口统一这些不同的半相关数据类型,所以我希望我们很快就会看到结果。对于容器类型也是如此。但结果不会是微不足道的。

这个包似乎提供了您想要的东西。我一直不明白为什么它不那么流行

撇开ListLike不谈,Prelude中没有实现这一点的一个原因是,如果不调用一些语言扩展(多参数类型类和FundeP或相关类型),就不可能做到这一点。有三种容器需要考虑:

  • 完全不关心其元素的容器(例如[])
  • 仅为特定元素实现的容器(例如ByTestRing)
  • 在元素上具有多态性但需要上下文的容器 (例如,Data.Vector.Storable 用可存储文件保存任何类型 实例)
  • 下面是一个非常基本的类似列表的样式类,不使用任何扩展:

    class Listable container where
      head :: container a -> a
    
    instance Listable [] where
      head (x:xs) = x
    
    instance Listable ByteString where --compiler error, wrong kind
    
    instance Listable SV.Vector where
      head v = SV.head    --compiler error, can't deduce context (Storable a)
    
    class Seq a b | a -> b where
      head :: a -> b
      isTail :: a -> Bool
    
    # ([a]) is a sequence of a's
    instance Seq [a] a where
      head (x:xs) = x
      isTail = (== [])
    
    # ByteString is a sequence of chars
    instance Seq ByteString Char
    
    这里的
    容器
    具有种类
    *->*
    。这不适用于ByTestRing,因为它们不允许任意类型;它们具有种类
    *
    。它也不适用于Data.Vector.Storable Vector,因为类不包含上下文(可存储约束)

    您可以通过将类定义更改为

    class ListableMPTC container elem | container -> elem where
    

    现在,
    container
    具有种类
    *
    ;它是一个完全应用的类型构造函数

    instance ListableMPTC [a] a where
    
    但你已经不再是一个单身汉了

    这就是为什么即使是一个简单的Listable类型接口也很重要的原因;当需要考虑不同的集合语义(例如队列)时,它会变得有点困难。另一个真正大的挑战是可变与不可变的数据。到目前为止,我所看到的每一次尝试(除了一次)通过创建一个可变接口和一个不可变接口来解决这个问题。我所知道的一个接口将这两个接口统一了起来,这是一个令人费解的接口,它调用了一系列扩展,性能非常差

    附录:BYTESTRING

    这完全是我的猜测,但我认为ByTestring是进化的产物。也就是说,它们是低性能I/O操作的第一个解决方案,使用
    Ptr Word8
    s与IO系统调用接口是有意义的。指针上的操作需要可存储的,而且很可能需要必要的扩展(如上所述)使多态性发挥作用在当时是不可用的。现在很难克服它们的势头。一个具有多态性的类似容器当然是可能的,storablevector包实现了这一点,但它远没有那么流行

    bytestring是否可以在不限制元素的情况下具有多态性?我认为Haskell与此最接近的是数组类型。对于低级别IO,这远不如bytestring好,因为需要将数据从指针解压到数组的内部格式。此外,数据被装箱,这会增加大量的空间开销。I如果您想要无绑定存储(更少的空间)和与C的高效接口,指针就是最好的选择。一旦您有了Ptr,您需要可存储,然后您需要在类型类中包含元素类型,这样您就只需要扩展了


    话虽如此,我认为有了适当的扩展,这对于任何单个容器实现(模可变/不可变API)来说本质上都是一个已解决的问题。现在更难的部分是提出一组合理的类,这些类可用于许多不同类型的结构(列表、数组、队列等)我个人认为这是相对简单的,但我可能错了。

    ByteString不是泛型类型

    在其他语言中,对于所有类似列表的数据结构,都有类似于
    Sequence
    。 我认为这是可行的,有正确的扩展:

    class Listable container where
      head :: container a -> a
    
    instance Listable [] where
      head (x:xs) = x
    
    instance Listable ByteString where --compiler error, wrong kind
    
    instance Listable SV.Vector where
      head v = SV.head    --compiler error, can't deduce context (Storable a)
    
    class Seq a b | a -> b where
      head :: a -> b
      isTail :: a -> Bool
    
    # ([a]) is a sequence of a's
    instance Seq [a] a where
      head (x:xs) = x
      isTail = (== [])
    
    # ByteString is a sequence of chars
    instance Seq ByteString Char
    
    还是试试这个

    type BS a = ByteString
    instance List BS
    

    在Haskell中为类似列表的数据创建一个类型类没有多大价值。为什么?是因为懒惰。您只需编写一个函数,将数据转换为列表,然后使用该列表。列表只会在需要其子列表和元素以及它们的内存时构建