2010-01-13 1 views
0

Учитывая следующий код:F #: Oddity с ленивым evalution

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». Что тут происходит?

ответ

4

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

+0

Возможно, я думаю, что мой VS2010 beta2 довольно старый: 10.0.21003.1. Кто-нибудь еще повторяет эту проблему? Если нет, я просто предполагаю, что это известная проблема с предыдущими версиями. – rysama

+0

Да, у меня нет Beta2, но моя внутренняя сборка на работе имеет ожидаемое поведение, поэтому, похоже, это была ошибка, которая была исправлена, не уверен, что исправление еще не привело его к выпуску. – Brian

+0

Спасибо за подтверждение – rysama

0

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

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

let bar = 
    lazy(
     printfn "bar"   
     42)