0 0

scala lazy的问题。5

初学scala,遇到一个lazy的问题。
scala> def repeat [T] (x : T) : List[T] = x :: (repeat (x))
scala> repeat (0) take (3)
结果堆栈溢出。
请问这个如何能处理为lazy的呢?

问题补充:邮件列表给出的答案是Stream类……
为什么scala不是默认lazy的呢……
FP 
2010年1月27日 11:31

2个答案 按时间排序 按投票排序

0 0

night_stalker 写道
val x = 12
lazy val repeat : List[Int] = x :: repeat

楼主要的不是那个意义上的lazy,而是跟Haskell一样的lazy evaluation,也就是说即便是无限表也有办法让某些运算能终结。

这样的话就应该自己写一个LazyList[T]类型,让它每到访问某个节点的时候才去计算其中的值。用内建的List[T]类型是做不到的,一对它求值它就会试图把整个表的值都先填上。

其实C#也能搞出类似效果的东西:
using System;
using System.Collections.Generic;
using System.Linq;

static class Program {
  static IEnumerable<T> Repeat<T>(T value) {
    while (true) {
      yield return value;
    }
  }
  
  static void Main(string[] args) {
    var repeat5 = Repeat(5);
    foreach (var n in repeat5.Take(3)) {
      Console.WriteLine(n);
    }
  }
}

也就是——作弊。
C#里的IEnumerable<T>就表示了一类lazy sequence,于是即便在这么一种strict evaluation order的语言里也照样可以无限repeat...

2010年1月29日 11:05
0 0

scala 中只有 val 才允许 lazy。所以不能用泛型。

val x = 12
lazy val repeat : List[Int] = x :: repeat


生搬 java 泛型真的很尴尬 …… 在 haskell 中很容易做的事情都变得很困难。

2010年1月29日 10:18

相关推荐

Global site tag (gtag.js) - Google Analytics