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
List Haskell-将两个列表合并为一个元组列表_List_Haskell_Tuples_Infinite - Fatal编程技术网

List Haskell-将两个列表合并为一个元组列表

List Haskell-将两个列表合并为一个元组列表,list,haskell,tuples,infinite,List,Haskell,Tuples,Infinite,我正在尝试实现一个函数(如下所述),它接受两个列表(每个列表或两个列表都可能是无限的),并返回列表之间所有可能的元素对的元组列表 zipInf :: [a] -> [b] -> [(a,b)] (例如,输出应如下所示,但不必完全如此) 我已经开始这样实施它: zipInf :: [a] -> [b] -> [(a,b)] zipInf [] _ = [] zipInf _ [] = [] zipInf 我想将列表输入一个helper函数来生成列表,但我创建的一个函数无

我正在尝试实现一个函数(如下所述),它接受两个列表(每个列表或两个列表都可能是无限的),并返回列表之间所有可能的元素对的元组列表

zipInf :: [a] -> [b] -> [(a,b)]
(例如,输出应如下所示,但不必完全如此)

我已经开始这样实施它:

zipInf :: [a] -> [b] -> [(a,b)]
zipInf [] _ = []
zipInf _ [] = []
zipInf
我想将列表输入一个helper函数来生成列表,但我创建的一个函数无法编译,并且不知道如何处理无限列表

辅助函数-

oneList :: [a] -> [b] [(a,b)]
oneList [] _ = []
oneList x:xs y:ys = [(x,y)] ++ oneList

您需要将
oneList
应用于
xs
ys

oneList :: [a] -> [b] -> [(a, b)]
oneList []     _      = []
oneList (x:xs) (y:ys) = (x, y) : oneList xs ys

无限列表将自动工作,因为Haskell是懒惰的。

以下是您发布的帮助函数:

oneList :: [a] -> [b] [(a,b)]
oneList [] _ = []
oneList x:xs y:ys = [(x,y)] ++ oneList
下面是它包含的语法错误:

  • 您在类型注释中遗漏了一个箭头;应该是

    oneList :: [a] -> [b] -> [(a,b)]
    
    zipInf :: [a] -> [b] -> [(a,b)]
    zipInf xs ys = thread (expand xs ys)
    
  • 您需要将非平凡模式包含在paren中,因此第二个等式应该开始

    oneList (x:xs) (y:ys) =
    
  • oneList
    在返回列表之前接受两个参数,但在第二个等式的rhs中,您尝试将其用作列表而不提供任何参数

(顺便说一句,如果你发布错误消息而不是仅仅说它无法编译,通常会对我们有所帮助。请将我上面指出的错误与编译器给你的错误消息进行比较。)


但正如您所注意到的,您的算法是错误的

我觉得这是家庭作业,所以我只想给你一个提示

zipInf
应该是

oneList :: [a] -> [b] -> [(a,b)]
zipInf :: [a] -> [b] -> [(a,b)]
zipInf xs ys = thread (expand xs ys)
thread
expand
是我留给您编写的两个带有类型签名的辅助函数

expand :: [a] -> [b] -> [[(a,b)]]
thread :: [[c]] -> [c]

expand
相当简单
thread
是您必须小心以正确的顺序包含元素的地方(因此,即使类型正确,您也不能只说
thread zs=concat zs

这是一个很好的练习

如果我们将您的输入对放在一个无限表中:

(0,A)  (1,A)  (2,A)  (3,A) ...
(0,B)  (1,B)  (2,B)  (3,B) ...
(0,C)  (1,C)  (2,C)  (3,C) ...
(0,D)  (1,D)  (2,D)  (3,D) ...
...
诀窍是以向上的对角线条纹横穿桌子。用你的眼睛跟踪桌子。此表的条纹为:

(0,A)
(0,B) (1,A)
(0,C) (1,B) (2,A)
(0,D) (1,C) (2,B) (3,A)
...
所有条纹都是有限的,但表中的每个元素都在其中一个条纹中,因此如果将它们连接在一起,则每个元素都将显示在连接结果中的有限位置

以下是我建议的游戏计划:

实现
条带::[[a]]->[[a]]
,它从上面的无限数组中提取条带列表(首先假设所有列表都是无限的,也就是说,不要担心
[]
情况;一旦您完成了该工作,请将其更正为在可能是有限的列表上工作)

使用
条纹
,实现连接所有条纹的
对角线::[[a]]->[a]
(这是一个单行程序)

最后,通过应用特定2D表格的
对角线
[[(a,b)]]
,实现您的功能,该表格是我开始回答此问题时使用的表格(可以使用嵌套列表理解和其他各种方式构建)

注:

  • zip这个名字有误导性。这更像是笛卡尔积

  • 你知道你可以在模式中匹配模式,对吗?例如,如果
    f::[[a]]->something

    f ((x:xs):xss) = ...
    
    x
    作为第一行的第一个元素,
    xs
    是第一行的其余部分,
    xss
    是表的其余部分


重要提示:请参见下面威尔·内斯的评论

你的问题意味着顺序无关紧要。(但由于列表可能是无限的,所以顺序可能比你想象的更重要!)无论如何,如果顺序不重要,并且你遇到了列表理解,那么这就是你可以使用的一种方法。这里有一个例子

λ> let xs = "abcdef"
λ> let ys = "ABCDEFGHI"
λ> [(x,y) | x <- xs, y <- ys]
[('a','A'),('a','B'),('a','C'),('a','D'),('a','E'),('a','F'),('a','G'),('a','H'),('a','I'),('b','A'),('b','B'),('b','C'),('b','D'),('b','E'),('b','F'),('b','G'),('b','H'),('b','I'),('c','A'),('c','B'),('c','C'),('c','D'),('c','E'),('c','F'),('c','G'),('c','H'),('c','I'),('d','A'),('d','B'),('d','C'),('d','D'),('d','E'),('d','F'),('d','G'),('d','H'),('d','I'),('e','A'),('e','B'),('e','C'),('e','D'),('e','E'),('e','F'),('e','G'),('e','H'),('e','I'),('f','A'),('f','B'),('f','C'),('f','D'),('f','E'),('f','F'),('f','G'),('f','H'),('f','I')]
但是像这样的一个需要很长时间:

(200000,'a') `elem` [(x,y) | x <- [1..], y <- ['a'..]]

(200000,'a')`elem`[(x,y)| x虽然这是理解列表和Haskell的一个很好的练习,但它也是理解
应用程序类的一个很好的练习。尤其是
[]
Applicative的实例。您想要的
zipInf
正是
liftA2(,)

我们只需要确保
[]
是一个
应用程序

λ: :i []
...
instance Applicative [] -- Defined in `Control.Applicative'
...
所以它是一个
应用程序
。如果我们稍微注释一下我们的类型,它可能会更容易理解

λ: :t liftA2 (,) `asAppliedTo` []
[a] -> [b] -> [(a, b)]
是的,那是同样的类型

λ: liftA2 (,) [0..2] ['A'..'C']
[(0,'A'),(0,'B'),(0,'C'),(1,'A'),(1,'B'),(1,'C'),(2,'A'),(2,'B'),(2,'C')]
看起来很有效! 所以你不必做任何事情来写这个,而且可以说它比递归定义更容易理解。另外,你不必像滚动你自己的解决方案那样担心边缘情况

您还可以使用
(或
fmap
)和
更惯用地编写它

另外,如果您想知道如何从
[]
Applicative
中获得不同的语义,那么
Applicative
至少还有一个列表实例:
ZipList

λ: :i ZipList
newtype ZipList a = ZipList {getZipList :: [a]}
    -- Defined in `Control.Applicative'
instance Functor ZipList -- Defined in `Control.Applicative'
instance Applicative ZipList -- Defined in `Control.Applicative'
此实例为其
Applicative
实例提供压缩样式语义

λ: getZipList $ (,) <$> ZipList [0..2] <*> ZipList ['A'..'C']
[(0,'A'),(1,'B'),(2,'C')]
λ:getZipList$(,)ZipList[0..2]ZipList['A'..'C']
[(0,'A'),(1,'B'),(2,'C')]

这两个都是对
Applicative
typeclass的很好的介绍,因为它们很容易获得,非常直观,有助于防止产生错误,并且显示了在某些情况下,单个类型有一个以上的typeclass实例。

您可以通过使用列表理解来实现这一点

zip::[a]->[b]->[(a,b)]
zip[].[]
zip[]=[]

zip as bs=[(a,b)| a和
((2,'a')`elem`……)需要多长时间
(当然假设无限字符类型(看起来确实如此))。这一点很好。如果其中一个列表是无限的,那么它将永远存在。只有第二个列表是无限的才会引起问题。@williness,
Char
有很多值,但它不是无限的。
(maxBound::Char)
λ: do {n <- [0..2]; c <- ['A'..'C']; return (n, c)}
[(0,'A'),(0,'B'),(0,'C'),(1,'A'),(1,'B'),(1,'C'),(2,'A'),(2,'B'),(2,'C')]
λ: :i ZipList
newtype ZipList a = ZipList {getZipList :: [a]}
    -- Defined in `Control.Applicative'
instance Functor ZipList -- Defined in `Control.Applicative'
instance Applicative ZipList -- Defined in `Control.Applicative'
λ: getZipList $ (,) <$> ZipList [0..2] <*> ZipList ['A'..'C']
[(0,'A'),(1,'B'),(2,'C')]
> zip [0..2] ['A'..'C']
[(0,'A'),(0,'B'),(0,'C'),(1,'A'),(1,'B'),(1,'C'),(2,'A'),(2,'B'),(2,'C')]

> take 50 $ zip [0..] ['A'..'C']
[(0,'A'),(0,'B'),(0,'C'),(1,'A'),(1,'B'),(1,'C'),(2,'A'),(2,'B'),(2,'C'),(3,'A'),(3,'B'),(3,'C'),(4,'A'),(4,'B'),(4,'C'),(5,'A'),(5,'B'),(5,'C'),(6,'A'),(6,'B'),(6,'C'),(7,'A'),(7,'B'),(7,'C'),(8,'A'),(8,'B'),(8,'C'),(9,'A'),(9,'B'),(9,'C'),(10,'A'),(10,'B'),(10,'C'),(11,'A'),(11,'B'),(11,'C'),(12,'A'),(12,'B'),(12,'C'),(13,'A'),(13,'B'),(13,'C'),(14,'A'),(14,'B'),(14,'C'),(15,'A'),(15,'B'),(15,'C'),(16,'A'),(16,'B')]

> take 50 $ zip [0..] [1..]
[(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(0,9),(0,10),(0,11),(0,12),(0,13),(0,14),(0,15),(0,16),(0,17),(0,18),(0,19),(0,20),(0,21),(0,22),(0,23),(0,24),(0,25),(0,26),(0,27),(0,28),(0,29),(0,30),(0,31),(0,32),(0,33),(0,34),(0,35),(0,36),(0,37),(0,38),(0,39),(0,40),(0,41),(0,42),(0,43),(0,44),(0,45),(0,46),(0,47),(0,48),(0,49),(0,50)]