3 people like it.

Nullable Refs without using AllowNullLiteral

Nullable Refs without using AllowNullLiteral

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
module NullRef =
  
  open System

  [<AllowNullLiteral>]
  type T<'a>(value:'a) =
    member internal x.Value = value

  let inline private isNull a = 
    Object.ReferenceEquals(box a, null)

  let create (value:'a) =
    new T<_>(value)

  let (@?) (a:T<'a>) (b:'a Lazy) = 
    if isNull a || isNull a.Value then 
      
      if isNull b then 
        failwith "Lazy object was null"

      let value = b.Value

      if isNull value then
        failwith "Lazy value was null"

      value

    else
      a.Value

open NullRef

type Foo() = class end

let z = create (Unchecked.defaultof<Foo>)
let d = z @? lazy Foo()
namespace System
Multiple items
type AllowNullLiteralAttribute =
  inherit Attribute
  new : unit -> AllowNullLiteralAttribute

Full name: Microsoft.FSharp.Core.AllowNullLiteralAttribute

--------------------
new : unit -> AllowNullLiteralAttribute
type T<'a> =
  new : value:'a -> T<'a>
  member internal Value : 'a

Full name: Script.NullRef.T<_>
val value : 'a
val x : T<'a>
member internal T.Value : 'a

Full name: Script.NullRef.T`1.Value
val private isNull : a:'a -> bool

Full name: Script.NullRef.isNull
val a : 'a
Multiple items
type Object =
  new : unit -> obj
  member Equals : obj:obj -> bool
  member GetHashCode : unit -> int
  member GetType : unit -> Type
  member ToString : unit -> string
  static member Equals : objA:obj * objB:obj -> bool
  static member ReferenceEquals : objA:obj * objB:obj -> bool

Full name: System.Object

--------------------
Object() : unit
Object.ReferenceEquals(objA: obj, objB: obj) : bool
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
val create : value:'a -> T<'a>

Full name: Script.NullRef.create
val a : T<'a>
val b : Lazy<'a>
Multiple items
active recognizer Lazy: Lazy<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.( |Lazy| )

--------------------
type Lazy<'T> =
  new : unit -> Lazy<'T> + 5 overloads
  member IsValueCreated : bool
  member ToString : unit -> string
  member Value : 'T

Full name: System.Lazy<_>

--------------------
Lazy() : unit
Lazy(valueFactory: Func<'T>) : unit
Lazy(isThreadSafe: bool) : unit
Lazy(mode: Threading.LazyThreadSafetyMode) : unit
Lazy(valueFactory: Func<'T>, isThreadSafe: bool) : unit
Lazy(valueFactory: Func<'T>, mode: Threading.LazyThreadSafetyMode) : unit
property T.Value: 'a
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
property Lazy.Value: 'a
module NullRef

from Script
Multiple items
type Foo =
  new : unit -> Foo

Full name: Script.Foo

--------------------
new : unit -> Foo
val z : T<Foo>

Full name: Script.z
module Unchecked

from Microsoft.FSharp.Core.Operators
val defaultof<'T> : 'T

Full name: Microsoft.FSharp.Core.Operators.Unchecked.defaultof
val d : Foo

Full name: Script.d

More information

Link:http://fssnip.net/3Y
Posted:5 years ago
Author:fholm
Tags: nullable