Skip to content

Commit

Permalink
Internal InlineIfLambda in NET45
Browse files Browse the repository at this point in the history
  • Loading branch information
wallymathieu committed Feb 13, 2024
1 parent 017d252 commit 09503a8
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 98 deletions.
91 changes: 2 additions & 89 deletions src/FSharpPlus/Builders.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ open System.ComponentModel
[<Obsolete("Compatibility with v1"); EditorBrowsable(EditorBrowsableState.Never)>]
module Builders =
open FSharpPlus.Operators
open FSharpPlus.Internals

// Idiom brackets
type Ii = Ii
Expand Down Expand Up @@ -100,6 +101,7 @@ module GenericBuilders =

open FSharpPlus.Operators
open FSharpPlus.Data
open FSharpPlus.Internals

// Idiom brackets
type Ii = Ii
Expand Down Expand Up @@ -153,61 +155,32 @@ module GenericBuilders =

type StrictBuilder<'``monad<'t>``> () =
inherit Builder<'``monad<'t>``> ()
#if !NET45
member inline _.Delay ([<InlineIfLambda>]expr) = expr : unit -> '``Monad<'T>``
member inline _.Run ([<InlineIfLambda>]f) = f () : '``monad<'t>``
member inline _.TryWith ([<InlineIfLambda>]expr, [<InlineIfLambda>]handler) = TryWith.InvokeForStrict expr handler : '``Monad<'T>``
member inline _.TryFinally ([<InlineIfLambda>]expr, [<InlineIfLambda>]compensation) = TryFinally.InvokeForStrict expr compensation : '``Monad<'T>``

member inline _.Using (disposable: #IDisposable, [<InlineIfLambda>]body) = Using.Invoke disposable body
#else
member inline _.Delay (expr) = expr : unit -> '``Monad<'T>``
member inline _.Run (f) = f () : '``monad<'t>``
member inline _.TryWith (expr, handler) = TryWith.InvokeForStrict expr handler : '``Monad<'T>``
member inline _.TryFinally (expr, compensation) = TryFinally.InvokeForStrict expr compensation : '``Monad<'T>``

member inline _.Using (disposable: #IDisposable, body) = Using.Invoke disposable body
#endif

type DelayedBuilder<'``monad<'t>``> () =
inherit Builder<'``monad<'t>``> ()
#if !NET45
member inline _.Delay ([<InlineIfLambda>]expr: _->'``Monad<'T>``) = Delay.Invoke expr : '``Monad<'T>``
member _.Run f = f : '``monad<'t>``
member inline _.TryWith (expr, [<InlineIfLambda>]handler ) = TryWith.Invoke expr handler : '``Monad<'T>``
member inline _.TryFinally (expr, [<InlineIfLambda>]compensation) = TryFinally.Invoke expr compensation : '``Monad<'T>``
member inline _.Using (disposable: #IDisposable, [<InlineIfLambda>]body) = Using.Invoke disposable body : '``Monad<'T>``
#else
member inline _.Delay (expr: _->'``Monad<'T>``) = Delay.Invoke expr : '``Monad<'T>``
member _.Run f = f : '``monad<'t>``
member inline _.TryWith (expr, handler ) = TryWith.Invoke expr handler : '``Monad<'T>``
member inline _.TryFinally (expr, compensation) = TryFinally.Invoke expr compensation : '``Monad<'T>``
member inline _.Using (disposable: #IDisposable, body) = Using.Invoke disposable body : '``Monad<'T>``
#endif

type MonadPlusStrictBuilder<'``monad<'t>``> () =
inherit StrictBuilder<'``monad<'t>``> ()
member _.YieldFrom expr = expr : '``monad<'t>``
member inline _.Zero () = Empty.Invoke () : '``MonadPlus<'T>``
#if !NET45
member inline _.Combine (a: '``MonadPlus<'T>``, [<InlineIfLambda>]b) = a <|> b () : '``MonadPlus<'T>``
#else
member inline _.Combine (a: '``MonadPlus<'T>``, b) = a <|> b () : '``MonadPlus<'T>``
#endif
#if !NET45
member inline _.While ([<InlineIfLambda>]guard, [<InlineIfLambda>]body: unit -> '``MonadPlus<'T>``) : '``MonadPlus<'T>`` =
#else
member inline _.While (guard, body: unit -> '``MonadPlus<'T>``) : '``MonadPlus<'T>`` =
#endif
let rec loop guard body =
if guard () then body () <|> loop guard body
else Empty.Invoke ()
loop guard body
#if !NET45
member inline this.For (p: #seq<'T>, [<InlineIfLambda>]rest: 'T->'``MonadPlus<'U>``) =
#else
member inline this.For (p: #seq<'T>, rest: 'T->'``MonadPlus<'U>``) =
#endif
Using.Invoke (p.GetEnumerator () :> IDisposable) (fun enum ->
let enum = enum :?> IEnumerator<_>
this.While (enum.MoveNext, fun () -> rest enum.Current) : '``MonadPlus<'U>``)
Expand All @@ -216,26 +189,14 @@ module GenericBuilders =
inherit StrictBuilder<'``monad<'t>``> ()

member inline _.Zero () = result () : '``Monad<unit>``
#if !NET45
member inline _.Combine (a: '``Monad<unit>``, [<InlineIfLambda>]b) = a >>= (fun () -> b ()) : '``Monad<'T>``
#else
member inline _.Combine (a: '``Monad<unit>``, b) = a >>= (fun () -> b ()) : '``Monad<'T>``
#endif

#if !NET45
member inline _.While ([<InlineIfLambda>]guard, [<InlineIfLambda>]body: unit -> '``Monad<unit>``) : '``Monad<unit>`` =
#else
member inline _.While (guard, body: unit -> '``Monad<unit>``) : '``Monad<unit>`` =
#endif
let rec loop guard body =
if guard () then body () >>= fun () -> loop guard body
else result ()
loop guard body
#if !NET45
member inline this.For (p: #seq<'T>, [<InlineIfLambda>]rest: 'T->'``Monad<unit>``) =
#else
member inline this.For (p: #seq<'T>, rest: 'T->'``Monad<unit>``) =
#endif
Using.Invoke (p.GetEnumerator () :> IDisposable) (fun enum ->
let enum = enum :?> IEnumerator<_>
this.While (enum.MoveNext, fun () -> rest enum.Current) : '``Monad<unit>``)
Expand All @@ -247,29 +208,17 @@ module GenericBuilders =
member inline _.Zero () = Empty.Invoke () : '``MonadPlus<'T>``
member inline _.Combine (a: '``MonadPlus<'T>``, b) = a <|> b : '``MonadPlus<'T>``

#if !NET45
member inline _.WhileImpl ([<InlineIfLambda>]guard, body: '``MonadPlus<'T>``) : '``MonadPlus<'T>`` =
#else
member inline _.WhileImpl (guard, body: '``MonadPlus<'T>``) : '``MonadPlus<'T>`` =
#endif
let rec fix () = Delay.Invoke (fun () -> if guard () then body <|> fix () else Empty.Invoke ())
fix ()

#if !NET45
member inline this.While ([<InlineIfLambda>]guard, body: '``MonadPlus<'T>``) : '``MonadPlus<'T>`` =
#else
member inline this.While (guard, body: '``MonadPlus<'T>``) : '``MonadPlus<'T>`` =
#endif
// Check the type is lazy, otherwise display a warning.
let __ () = TryWith.InvokeForWhile (Unchecked.defaultof<'``MonadPlus<'T>``>) (fun (_: exn) -> Unchecked.defaultof<'``MonadPlus<'T>``>) : '``MonadPlus<'T>``

this.WhileImpl (guard, body)

#if !NET45
member inline this.For (p: #seq<'T>, [<InlineIfLambda>]rest: 'T->'``MonadPlus<'U>``) : '``MonadPlus<'U>`` =
#else
member inline this.For (p: #seq<'T>, rest: 'T->'``MonadPlus<'U>``) : '``MonadPlus<'U>`` =
#endif
let mutable isReallyDelayed = true
Delay.Invoke (fun () -> isReallyDelayed <- false; Empty.Invoke () : '``MonadPlus<'U>``) |> ignore
Using.Invoke (p.GetEnumerator () :> IDisposable) (fun enum ->
Expand Down Expand Up @@ -297,30 +246,18 @@ module GenericBuilders =

member inline _.Combine (a: '``Monad<unit>``, b) = a >>= (fun () -> b) : '``Monad<'T>``

#if !NET45
member inline _.WhileImpl ([<InlineIfLambda>]guard, body: '``Monad<unit>``) : '``Monad<unit>`` =
#else
member inline _.WhileImpl (guard, body: '``Monad<unit>``) : '``Monad<unit>`` =
#endif
let rec loop guard body =
if guard () then body >>= (fun () -> loop guard body)
else result ()
loop guard body

#if !NET45
member inline this.While ([<InlineIfLambda>]guard, body: '``Monad<unit>``) : '``Monad<unit>`` =
#else
member inline this.While (guard, body: '``Monad<unit>``) : '``Monad<unit>`` =
#endif
// Check the type is lazy, otherwise display a warning.
let __ () = TryWith.InvokeForWhile (Unchecked.defaultof<'``Monad<unit>``>) (fun (_: exn) -> Unchecked.defaultof<'``Monad<unit>``>) : '``Monad<unit>``
this.WhileImpl (guard, body)

#if !NET45
member inline this.For (p: #seq<'T>, [<InlineIfLambda>]rest: 'T->'``Monad<unit>``) : '``Monad<unit>``=
#else
member inline this.For (p: #seq<'T>, rest: 'T->'``Monad<unit>``) : '``Monad<unit>``=
#endif
let mutable isReallyDelayed = true
Delay.Invoke (fun () -> isReallyDelayed <- false; Return.Invoke () : '``Monad<unit>``) |> ignore
Using.Invoke (p.GetEnumerator () :> IDisposable) (fun enum ->
Expand All @@ -334,11 +271,7 @@ module GenericBuilders =
member _.ReturnFrom (expr) = expr : '``applicative<'t>``
member inline _.Return (x: 'T) = result x : '``Applicative<'T>``
member inline _.Yield (x: 'T) = result x : '``Applicative<'T>``
#if !NET45
member inline _.BindReturn(x, [<InlineIfLambda>]f) = map f x : '``Applicative<'U>``
#else
member inline _.BindReturn(x, f) = map f x : '``Applicative<'U>``
#endif
member inline _.MergeSources (t1: '``Applicative<'T>``, t2: '``Applicative<'U>``) : '``Applicative<'T * 'U>`` = Lift2.Invoke tuple2 t1 t2
member inline _.MergeSources3 (t1: '``Applicative<'T>``, t2: '``Applicative<'U>``, t3: '``Applicative<'V>``) : '``Applicative<'T * 'U * 'V>`` = Lift3.Invoke tuple3 t1 t2 t3
member _.Run f = f : '``Applicative<'T>``
Expand All @@ -348,11 +281,7 @@ module GenericBuilders =
member _.ReturnFrom expr : '``applicative1<applicative2<'t>>`` = expr
member inline _.Return (x: 'T) : '``Applicative1<Applicative2<'T>>`` = (result >> result) x
member inline _.Yield (x: 'T) : '``Applicative1<Applicative2<'T>>`` = (result >> result) x
#if !NET45
member inline _.BindReturn (x: '``Applicative1<Applicative2<'T>>``, [<InlineIfLambda>]f: _ -> _) : '``Applicative1<Applicative2<'U>>`` = (map >> map) f x
#else
member inline _.BindReturn (x: '``Applicative1<Applicative2<'T>>``, f: _ -> _) : '``Applicative1<Applicative2<'U>>`` = (map >> map) f x
#endif
member inline _.MergeSources (t1, t2) : '``Applicative1<Applicative2<'T>>`` = (lift2 >> lift2) tuple2 t1 t2
member inline _.MergeSources3 (t1, t2, t3) : '``Applicative1<Applicative2<'T>>`` = (lift3 >> lift3) tuple3 t1 t2 t3
member _.Run x : '``Applicative1<Applicative2<'T>>`` = x
Expand All @@ -362,11 +291,7 @@ module GenericBuilders =
member _.ReturnFrom expr : '``applicative1<applicative2<applicative3<'t>>>`` = expr
member inline _.Return (x: 'T) : '``Applicative1<Applicative2<Applicative3<'T>>>`` = (result >> result >> result) x
member inline _.Yield (x: 'T) : '``Applicative1<Applicative2<Applicative3<'T>>>`` = (result >> result >> result) x
#if !NET45
member inline _.BindReturn (x: '``Applicative1<Applicative2<Applicative3<'T>>>``, [<InlineIfLambda>]f: _ -> _) : '``Applicative1<Applicative2<'U>>`` = (map >> map >> map) f x
#else
member inline _.BindReturn (x: '``Applicative1<Applicative2<Applicative3<'T>>>``, f: _ -> _) : '``Applicative1<Applicative2<'U>>`` = (map >> map >> map) f x
#endif
member inline _.MergeSources (t1, t2) : '``Applicative1<Applicative2<Applicative3<'T>>>`` = (lift2 >> lift2 >> lift2) tuple2 t1 t2
member inline _.MergeSources3 (t1, t2, t3) : '``Applicative1<Applicative2<Applicative3<'T>>>`` = (lift3 >> lift3 >> lift3) tuple3 t1 t2 t3
member _.Run x : '``Applicative1<Applicative2<Applicative3<'T>>>`` = x
Expand All @@ -377,11 +302,7 @@ module GenericBuilders =
member _.ReturnFrom (expr) = expr : '``applicative<'t>``
member inline _.Return (x: 'T) = pur x : '``Applicative<'T>``
member inline _.Yield (x: 'T) = pur x : '``Applicative<'T>``
#if !NET45
member inline _.BindReturn(x, [<InlineIfLambda>]f) = map f x : '``Applicative<'U>``
#else
member inline _.BindReturn(x, f) = map f x : '``Applicative<'U>``
#endif
member inline _.MergeSources (t1: '``Applicative<'T>``, t2: '``Applicative<'U>``) : '``Applicative<'T * 'U>`` = map2 tuple2 t1 t2
member inline _.MergeSources3 (t1: '``Applicative<'T>``, t2: '``Applicative<'U>``, t3: '``Applicative<'V>``) : '``Applicative<'T * 'U * 'V>`` = map3 tuple3 t1 t2 t3
member _.Run f : '``Applicative<'T>`` = f
Expand All @@ -391,11 +312,7 @@ module GenericBuilders =
member _.ReturnFrom expr : '``applicative1<applicative2<'t>>`` = expr
member inline _.Return (x: 'T) : '``Applicative1<Applicative2<'T>>`` = (pur >> pur) x
member inline _.Yield (x: 'T) : '``Applicative1<Applicative2<'T>>`` = (pur >> pur) x
#if !NET45
member inline _.BindReturn (x: '``Applicative1<Applicative2<'T>>``, [<InlineIfLambda>]f: _ -> _) : '``Applicative1<Applicative2<'U>>`` = (map >> map) f x
#else
member inline _.BindReturn (x: '``Applicative1<Applicative2<'T>>``, f: _ -> _) : '``Applicative1<Applicative2<'U>>`` = (map >> map) f x
#endif
member inline _.MergeSources (t1, t2) : '``Applicative1<Applicative2<'T>>`` = (map2 >> map2) tuple2 t1 t2
member inline _.MergeSources3 (t1, t2, t3) : '``Applicative1<Applicative2<'T>>`` = (map3 >> map3) tuple3 t1 t2 t3
member _.Run x : '``Applicative1<Applicative2<'T>>`` = x
Expand All @@ -405,11 +322,7 @@ module GenericBuilders =
member _.ReturnFrom expr : '``applicative1<applicative2<applicative3<'t>>>`` = expr
member inline _.Return (x: 'T) : '``Applicative1<Applicative2<Applicative3<'T>>>`` = (pur >> pur >> pur) x
member inline _.Yield (x: 'T) : '``Applicative1<Applicative2<Applicative3<'T>>>`` = (pur >> pur >> pur) x
#if !NET45
member inline _.BindReturn (x: '``Applicative1<Applicative2<Applicative3<'T>>>``, [<InlineIfLambda>]f: _ -> _) : '``Applicative1<Applicative2<'U>>`` = (map >> map >> map) f x
#else
member inline _.BindReturn (x: '``Applicative1<Applicative2<Applicative3<'T>>>``, f: _ -> _) : '``Applicative1<Applicative2<'U>>`` = (map >> map >> map) f x
#endif
member inline _.MergeSources (t1, t2) : '``Applicative1<Applicative2<Applicative3<'T>>>`` = (map2 >> map2 >> map2) tuple2 t1 t2
member inline _.MergeSources3 (t1, t2, t3) : '``Applicative1<Applicative2<Applicative3<'T>>>`` = (map3 >> map3 >> map3) tuple3 t1 t2 t3
member _.Run x : '``Applicative1<Applicative2<Applicative3<'T>>>`` = x
Expand Down
2 changes: 1 addition & 1 deletion src/FSharpPlus/Control/Traversable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ type Traverse =
[<Obsolete;CompiledName("Traverse")>]
static member TraverseLegacy (t:'t seq ,f:'t->'u option , [<Optional>]_output:option<seq<'u>>, [<Optional>]_impl:Default2): seq<'u> option =
let mapped = Seq.map f t
Sequence.ForInfiniteSequences (mapped, IsLeftZero.Invoke, List.toSeq)
Sequence.ForInfiniteSequences (mapped, IsLeftZero.Invoke, List.toSeq, Return.Invoke)

type Sequence with

Expand Down
5 changes: 1 addition & 4 deletions src/FSharpPlus/Extensions/Result.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace FSharpPlus
module Result =
open FSharp.Core.CompilerServices
open System
open FSharpPlus.Internals

/// Creates an Ok with the supplied value.
[<Obsolete("Prefer Result.Ok")>]
Expand Down Expand Up @@ -99,11 +100,7 @@ module Result =
/// Error "Hello world" |> Result.iter (printfn "%s") // prints "Hello world"
/// </code>
/// </example>
#if !NET45
let inline iterError ([<InlineIfLambda>]action: 'Error -> unit) (source: Result<'T, 'Error>) = match source with Ok _ -> () | Error x -> action x
#else
let inline iterError (action: 'Error -> unit) (source: Result<'T, 'Error>) = match source with Ok _ -> () | Error x -> action x
#endif

/// <summary>Extracts a value from either side of a Result.</summary>
/// <param name="fOk">Function to be applied to source, if it contains an Ok value.</param>
Expand Down
6 changes: 6 additions & 0 deletions src/FSharpPlus/Internals.fs
Original file line number Diff line number Diff line change
Expand Up @@ -517,3 +517,9 @@ module FindLastSliceIndex =
exception AggregateException of Exception seq

#endif

#if NET45
type InlineIfLambdaAttribute()=class
inherit Attribute()
end
#endif
6 changes: 2 additions & 4 deletions src/FSharpPlus/Operators.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace FSharpPlus

open System
open FSharpPlus.Control
open FSharpPlus.Internals

/// Generic functions and operators
[<AutoOpenAttribute>]
Expand Down Expand Up @@ -58,11 +59,8 @@ module Operators =
/// Executes a side-effect function and returns the original input value. Same as 'tap' but with arguments flipped.
/// </summary>
/// <category index="0">Common Combinators</category>
#if !NET45
let inline (|-) source ([<InlineIfLambda>]f: 'T -> unit) = f source; source
#else
let inline (|-) source (f: 'T -> unit) = f source; source
#endif


/// <summary>
/// Executes a side-effect function and returns the original input value.
Expand Down

0 comments on commit 09503a8

Please sign in to comment.