F #: Странность с ленивой оценкой - PullRequest
0 голосов
/ 13 января 2010

С учетом следующего кода:

let bar =
    lazy(
        printfn "bar"        
        ())

let foo = 
    lazy(
        printfn "foo"
        bar)

В интерактивном окне (его сброс каждый раз),

Когда я звоню let res = foo.Force (), я получаю:

foo
val res : Lazy<unit> = Value is not created.

Когда я просто звоню foo.Force() , я получаю:

foo
bar
val it : Lazy<unit> =
  <ToString exception: Object reference not set to an instance of an object.>
    {IsValueCreated = false;
     Value = null;}

В обоих случаях я бы ожидал, что он просто напечатает "foo", однако во втором случае вы увидите "foo \ nbar" Что здесь происходит?

Ответы [ 2 ]

4 голосов
/ 13 января 2010

Какая версия F # у вас есть? Это может звучать как ошибка, которая была исправлена; когда FSI печатает значение типа Lazy <'a>, в какой-то момент я думаю, что ToString () отображает значение, используемое для того, чтобы ленивый печатал его, тогда как теперь это не так.

0 голосов
/ 14 января 2010

Проблема, похоже, в деталях реализации. Как ссылка Lazy узнает, когда она вычислила значение? Может быть, когда это ссылка не ().

Наличие типа Lazy<unit> не имеет особого смысла. Попробуйте

let bar =
    lazy(
        printfn "bar"        
        42)
...