11 people like it.

Adding two numbers has never been this awful

Normally, you'd add two numbers with the '+' operator. But why do that when you can use Type Extensions, custom operations on Computation Expressions, customer operators, and more?

 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: 
module Hoopty =
    [<AutoOpen>]
    module Doopty =
        [<Measure>] type doot
        [<Measure>] type hoopty

        type Ref<'T> with
            member __.ReturnFrom(x) = x
            [<CustomOperation("GIANT_DAD")>]
            member __.Doot(_state: Ref<_>, x) = x
            member __.Yield(x) = ref x

        let inline (?^&>.<) x y = (y, !x) ||> (+)
        let inline derp (x: Ref<_>) y =
            x {
                GIANT_DAD (x ?^&>.< y)
            }

    let inline add x y =
        ref 1000<doot/hoopty>
            {            return! derp (ref x) y
}

printfn "%d" (Hoopty.add 1 2) // 3
printfn "%f" (Hoopty.add 1. 2.) // 3.000000
Multiple items
type AutoOpenAttribute =
  inherit Attribute
  new : unit -> AutoOpenAttribute
  new : path:string -> AutoOpenAttribute
  member Path : string

Full name: Microsoft.FSharp.Core.AutoOpenAttribute

--------------------
new : unit -> AutoOpenAttribute
new : path:string -> AutoOpenAttribute
Multiple items
type MeasureAttribute =
  inherit Attribute
  new : unit -> MeasureAttribute

Full name: Microsoft.FSharp.Core.MeasureAttribute

--------------------
new : unit -> MeasureAttribute
[<Measure>]
type doot

Full name: Script.Hoopty.Doopty.doot
[<Measure>]
type hoopty

Full name: Script.Hoopty.Doopty.hoopty
member Ref.ReturnFrom : x:'a -> 'a

Full name: Script.Hoopty.Doopty.ReturnFrom
val x : 'a
Multiple items
type CustomOperationAttribute =
  inherit Attribute
  new : name:string -> CustomOperationAttribute
  member AllowIntoPattern : bool
  member IsLikeGroupJoin : bool
  member IsLikeJoin : bool
  member IsLikeZip : bool
  member JoinConditionWord : string
  member MaintainsVariableSpace : bool
  member MaintainsVariableSpaceUsingBind : bool
  member Name : string
  ...

Full name: Microsoft.FSharp.Core.CustomOperationAttribute

--------------------
new : name:string -> CustomOperationAttribute
val __ : Ref<'T>
member Ref.Doot : _state:Ref<'a> * x:'b -> 'b

Full name: Script.Hoopty.Doopty.Doot
val x : 'b
member Ref.Yield : x:'a -> 'a ref

Full name: Script.Hoopty.Doopty.Yield
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val x : 'a ref (requires member ( + ))
val y : 'b (requires member ( + ))
val derp : x:Ref<'a> -> y:'b -> 'c (requires member ( + ))

Full name: Script.Hoopty.Doopty.derp
val x : Ref<'a> (requires member ( + ))
custom operation: GIANT_DAD ('b)

Calls Ref.Doot
val add : x:'a -> y:'b -> 'c (requires member ( + ))

Full name: Script.Hoopty.add
val x : 'a (requires member ( + ))
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
module Hoopty

from Script
Raw view Test code New version

More information

Link:http://fssnip.net/7UW
Posted:5 years ago
Author:Phillip Carter
Tags: computation expression , custom operator , extension , custom operation