Ответ 1
До .NET 4.0 инфраструктура не поставлялась с Lazy<'T>
.
Эта древняя история, но F # первоначально имела свою собственную реализацию Lazy
, отличную от того, что у нас есть сегодня - вы можете увидеть ее здесь.
Эта реализация была оставлена, когда стало ясно, что Lazy
подходит к самой структуре. Вместо этого F # 2.0 поставляется с собственной реализацией System.Lazy<'T>
(обратите внимание на пространство имен) в сборке FSharp.Core
. В этой реализации вы все еще можете увидеть здесь. Идея заключалась в том, что, как только .NET 4.0 будет доступен, F # будет без проблем собирать System.Lazy<'T>
вместо этого, не нарушая пользователей. Это работало по большей части, но это было не совсем без проблем.
Вы заметите, что реализация F # имеет член CreateFromValue
, который дает значение типа Lazy<'T>
, уже отмеченное как оцененное. Это имеет смысл в семантическом смысле, поскольку вы, очевидно, даете ему оцененное значение в первую очередь.
Почему тогда реализация .NET 4.0 не делает то же самое?
Если вы посмотрите documentation для Lazy<'T>
, вы обнаружите, что нет способа создать его в оцениваемом состоянии. На нем нет элемента CreateFromValue
, и никакой конструктор не принимает значение 'T
, а только Func<'T>
. CreateFromValue
фактически предоставляется как метод расширения с помощью F #.
Было бы довольно легко обеспечить этот метод неразрывным способом:
static member CreateFromValue(value : 'T) : System.Lazy<'T> =
let x = System.Lazy<'T>.Create(fun () -> value)
x.Value |> ignore
x
но по какой-то причине этого не произошло. Возможно, это был преднамеренный выбор - я полагаю, вы могли бы спорить и против таких изменений, и, возможно, это был надзор. Если вы посмотрите на свернутую историю этого типа, я думаю, вы согласитесь, что это могло быть хуже.