繁体   English   中英

Haskell,自然数列表

[英]Haskell, list of natural number

我是 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)),...]无限列表,您可以使用iterate fx ,例如iterate (*2) 1将返回列表[1, 2, 4, 16,...]

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

mulstream s1 s2 = zipWith (*) s1 s2

为了使这个定义更简洁,您可以使用无点形式:

mulstream = zipWith (*)

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

num1 = 1 : map (+1) num1

或者理解:

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

或者当然:

num3 = [1..]

我不确定这是不是你问的问题,但在我看来,你想要建立一个增加自然数的列表,而不依赖于任何其他列表。 所以,通过这个标记,你可以做一些事情

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 :)

语言中有这样的语法:

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]

您可以定义一个最多达到某个数字的列表,然后通过保持前者不变来将第一个与第二个相加,如下所示:

naturals :: Integer -> [Integer]
naturals n
  | n <= 0    = []
  | otherwise = nat n []
    where
      nat 1 a = (1:a)
      nat n a = nat (n-k) (nat k a)
        where
          k = (n-1)

sumNaturals :: [Integer] -> [Integer]
sumNaturals l = sumRight l []
  where
    sumRight [] a = a
    sumRight (x:[]) a = (x:a)
    sumRight (x:y:zs) a = sumRight (x:a) (sumRight (sum (x:y:a):zs) a)

由于它们都是 1,您可以通过更改它们总和的顺序,以您喜欢的任何方式增加它们,从左到右,到中间点等等。 您可以使用以下方法测试最多一百(或更多):

(sumNaturals . naturals) 100

暂无
暂无

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

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