繁体   English   中英

列表或元组元组的列表

[英]A list of list or a tuple of tuples

我只是想知道是否有可能创建一个返回(希望是无限的)数字列表的函数。 [1,[2,[3,[4]]]]。

我得到的最接近的是这个。

func list 0 = list
func list num = func newList (num-1) 
                where newList = list ++ [[num]]

这是用这样的。

func [] 3

哪个回来了。

[[3],[2],[1]]

现在我知道这不是无限的,也不是正确的顺序,但我只是想表明我至少在发布之前尝试了一些东西。 :)

谢谢你!

您不能编写这样的函数,因为列表的所有元素必须具有相同的类型。 即使仅有两个元素,您要创建的列表也不会进行类型检查:

Prelude> :t [1::Int,[2::Int]]

<interactive>:1:9:
    Couldn't match expected type `Int' with actual type `[Int]'
    In the expression: [2 :: Int]
    In the expression: [1 :: Int, [2 :: Int]]

第一个元素是Int,第二个元素是Int列表,因此类型检查失败。

虽然你可以用元组表达结果,例如

Prelude> :t (1::Int,(2::Int,(3::Int,4::Int)))
(1::Int,(2::Int,(3::Int,4::Int))) :: (Int, (Int, (Int, Int)))

您仍然无法编写该函数,因为结果的类型将根据您希望拥有的元素数量而改变。 让我们把f假设的功能:

f 1 :: (Int)
f 2 :: (Int,(Int))
f 3 :: (Int,(Int,(Int)))
...

f的类型随参数而变化,因此无法写入f

关键是要提出正确的类型。

如果你想要[1, [2, [3, [4]]]]这样的东西,那么完全不行,因为所有列表元素必须是相同的类型。

这是有道理的,因为当我从列表中抓取一个元素时,我需要先知道它是什么类型才能用它做任何事情(这是类型的全部点,它们告诉你你能做什么,能做什么'做一件事)。

但是由于Haskell的类型系统是静态的,我需要知道它是什么类型,即使不知道列表中的哪个元素 ,因为在程序运行之前我可能不知道哪个列表索引。 所以无论我使用什么索引,我都必须得到相同类型的东西。

但是,可以像你想要的那样做一些事情:你想要一个可能是整数的数据类型,或者可能是一个列表:

type IntegerOrList a = Either Integer [a]

如果您不熟悉Either类型,则对于某些x :: lEither lr的值可以是Left x ,对于某些y :: r ,可以是Right y 因此IntegerOrList a是一个类型,其值可以是整数或某些列表。 所以我们可以列出这些东西:以下是[IntegerOrList Bool]类型的值:

[Left 7, Left 4, Right [True, False], Left 8, Right [], Right [False]]

好的,所以这是列表中的一个列表级别,但是我们不能将列表放在列表中的列表中 - 内部列表包含Bool s,它不能是列表。 如果我们改为[IntegerOrList (IntegerOrList Bool)] ,我们就可以在列表中的列表中包含列表,但是我们仍然没有得到进一步的结果。 在我们的示例中,我们有一个列表,其中包含整数或列表的值,列表是包含整数或列表值的列表,以及...我们真正想要的是IntegerOrList (IntegerOrList (IntegerOrList ... ,或更简单地说,像:

type IntegerOrLists = Either Integer [IntegerOrLists]

但是这是不允许的 - 类型同义词不能递归,因为这会产生一个无限大的类型,这对于糟糕的编译器来说很困惑。 但是,正确的数据类型可以递归:

data IntegerOrLists = I Integer | L [IntegerOrLists]

现在您可以构建这样的列表,混合整数和类型列表:

L [I 1, L [I 2, L [I 3, L [I 4]]]]

关键是必须使用IL构造函数标记每个项是整数还是列表。 现在列表的每个元素都是IntegerOrLists类型,我们可以通过查看该构造函数来区分它。 所以typechecker终于开心了。

{-# LANGUAGE ExistentialQuantification #-}

class Foo a

instance Foo Int
instance Foo [a]

data F = forall a. Foo a => F a

test = F [F (1 :: Int), F [F (2 :: Int), F [F (3 :: Int), F [F (4 :: Int)]]]]

这个例子说明了

  • 你可以在Haskell中拥有这样的结构,只需使用一些礼品包装
  • 这些结构几乎没用(尝试用它做点什么)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM