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/9.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_Stream_Lazy Evaluation - Fatal编程技术网

List Haskell,自然数列表

List Haskell,自然数列表,list,haskell,stream,lazy-evaluation,List,Haskell,Stream,Lazy Evaluation,我在Haskell是一个绝对的新手,但我试图了解它是如何工作的 我想写我自己的惰性整数列表,比如[1,2,3,4,5…] 我已经写过的清单 ones = 1 : ones 尝试后,效果良好: *Main> take 10 ones [1,1,1,1,1,1,1,1,1,1] 如何对递增整数执行相同的操作 我尝试过这个方法,但确实失败了: int = 1 : head[ int + 1] 在那之后,我怎样才能得到一个将两条流相乘的方法呢?例如: mulstream s1 s2 = h

我在Haskell是一个绝对的新手,但我试图了解它是如何工作的

我想写我自己的惰性整数列表,比如[1,2,3,4,5…]

我已经写过的清单

ones = 1 : ones
尝试后,效果良好:

*Main> take 10 ones
[1,1,1,1,1,1,1,1,1,1]
如何对递增整数执行相同的操作

我尝试过这个方法,但确实失败了:

int  = 1 : head[ int + 1]
在那之后,我怎样才能得到一个将两条流相乘的方法呢?例如:

mulstream s1 s2 = head[s1] * head[s2] : mulstream [tail s1] [tail s2]

int=1:head[int+1]
不起作用的原因是:

  • head返回单个元素,但是
    的第二个参数需要是一个列表
  • int+1
    尝试添加列表和数字,但这是不可能的
创建从1递增到无穷大的列表的最简单方法是
[1..]

要按除1以外的步骤计数,您可以使用
[firstElement,secondElement..]
,例如,创建所有正奇数整数的列表:[1,3..]

要获得形式为
[x,fx,f(fx),f(f(fx)),…]的无限列表,可以使用
迭代fx
,例如
迭代(*2)1
将返回列表
[1,2,4,16,…]

要在两个列表的每对元素上成对应用操作,请使用zipWith:

mulstream s1 s2 = zipWith (*) s1 s2
要使此定义更简洁,可以使用无点形式:

mulstream = zipWith (*)

对于自然数,您必须使用地图:

num1 = 1 : map (+1) num1
或理解:

num2 = 1 : [x+1 | x <- num2]

语言中有这样的语法:

take 10 [1,2..]

=> [1,2,3,4,5,6,7,8,9,10]
您甚至可以进行不同的跨步:

take 10 [1,3..]
=> [1,3,5,7,9,11,13,15,17,19]

我不确定这是否是你要问的,但在我看来,你想建立一个自然数递增的列表,而不依赖任何其他列表。因此,出于这个原因,你可以这样做

incr a = a : inrc (a+1)
lst = inrc 1

take 3 lst
=> [1,2,3]
从技术上讲,这被称为累积函数(我相信),然后我们所做的就是将它的一个特例轻松地与“lst”一起使用

你可以从那里发疯,做如下事情:

lst = 1 : incr lst where incr a = (head a) + 1 : incr (tail a)

take 3 lst
=> [1,2,3]
诸如此类,虽然这可能依赖于一些你还没有学过的东西(在哪里)——从OP判断——但它仍然应该很容易阅读

哦,对了,然后是列表乘法。好的,你可以像上面提到的那样使用zipWith(*),或者你可以像这样重新发明轮子(相信我,这更有趣!)


safemul的原因,我相信,你可以通过实验这个函数找到,但它与“tail”有关。问题是,不存在空列表、不匹配列表等情况,因此您要么必须将各种定义(lmul[]=[])拼凑在一起,要么使用防护和/或where等等。。。或者坚持使用zipWith:)

您可能会对()和[]之间的区别感到困惑,因为如果您将所有[]替换为(),您的上一个示例将起作用(对于无限列表)。或者也可以使用
nat=1:map such nat
lst = 1 : incr lst where incr a = (head a) + 1 : incr (tail a)

take 3 lst
=> [1,2,3]
lmul a b = (head a * head b) : lmul (tail a) (tail b) 
safemul a b = take (minimum [len a, len b]) (lmul a b)