我是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]
答案 0 :(得分:21)
int = 1 : head [ int + 1]
不起作用的原因是:
:
的第二个参数需要是一个列表。int + 1
尝试添加列表和数字,这是不可能的。创建从1到无穷大的列表的最简单方法是[1..]
要以1以外的步数进行计数,您可以使用[firstElement, secondElement ..]
,例如创建所有正奇数整数的列表:[1,3 ..]
要获取表单[x, f x, f (f x), f (f (f x)),...]
的无限列表,您可以使用iterate f x
,例如iterate (*2) 1
将返回列表[1, 2, 4, 16,...]
。
要在两个列表的每对元素上成对应用操作,请使用zipWith:
mulstream s1 s2 = zipWith (*) s1 s2
为了使这个定义更简洁,您可以使用无点形式:
mulstream = zipWith (*)
答案 1 :(得分:17)
对于自然数字,您必须使用map:
num1 = 1 : map (+1) num1
或者理解:
num2 = 1 : [x+1 | x <- num2]
当然还是:
num3 = [1..]
答案 2 :(得分:4)
我不确定这是不是你问的问题,但在我看来,你想要建立一个增加自然数的列表,而不依赖于任何其他列表。因此,通过该令牌,您可以执行诸如
之类的操作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(*),或者你可以像这样重新发明轮子(它更有趣,相信我:)
lmul a b = (head a * head b) : lmul (tail a) (tail b)
safemul a b = take (minimum [len a, len b]) (lmul a b)
安全的原因,我相信,你可以通过试验这个功能找到答案,但它与'尾'有关。问题是,没有空列表,列表不匹配等情况,所以你要么必须将各种定义(lmul _ [] = [])或者使用警卫和/或等等一起破解。 ...或坚持使用zipWith:)
答案 3 :(得分:2)
语言中有这样的语法:
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]