diff --git a/docsrc/content/abstraction-applicative.fsx b/docsrc/content/abstraction-applicative.fsx index 29d4da0b0..4db23f5e8 100644 --- a/docsrc/content/abstraction-applicative.fsx +++ b/docsrc/content/abstraction-applicative.fsx @@ -65,6 +65,7 @@ From F# - ``Choice<'T,'U>`` - ``KeyValuePair<'Key,'T>`` - ``'Monoid * 'T`` + - ``'ValueTuple`` - ``Task<'T>`` - ``'R->'T`` - ``Expr<'T>`` diff --git a/docsrc/content/abstraction-bifoldable.fsx b/docsrc/content/abstraction-bifoldable.fsx index fa882c329..01fdad8a4 100644 --- a/docsrc/content/abstraction-bifoldable.fsx +++ b/docsrc/content/abstraction-bifoldable.fsx @@ -78,6 +78,7 @@ Concrete implementations From .Net/F# - ``'T * 'U`` + - ``struct ('T * 'U)`` - ``Result<'T,'U>`` - ``Choice<'T,'U>`` diff --git a/docsrc/content/abstraction-bifunctor.fsx b/docsrc/content/abstraction-bifunctor.fsx index 9286c232f..ddefd7975 100644 --- a/docsrc/content/abstraction-bifunctor.fsx +++ b/docsrc/content/abstraction-bifunctor.fsx @@ -67,6 +67,7 @@ Concrete implementations of Bifunctor<'T1,'T2> From .Net/F# - ``'T1 * 'T2`` + - ``struct ('T1 * 'T2)`` - ``Result<'T2,'T1>`` - ``Choice<'T2,'T1>`` - ``KeyValuePair<'T1,'T2>`` diff --git a/docsrc/content/abstraction-bitraversable.fsx b/docsrc/content/abstraction-bitraversable.fsx index 4aa9e7e21..ee0210d2f 100644 --- a/docsrc/content/abstraction-bitraversable.fsx +++ b/docsrc/content/abstraction-bitraversable.fsx @@ -53,6 +53,7 @@ Concrete implementations From .Net/F# - ``'T * 'U`` +- ``struct ('T * 'U)`` - ``Result<'T,'U>`` - ``Choice<'T,'U>`` diff --git a/docsrc/content/abstraction-comonad.fsx b/docsrc/content/abstraction-comonad.fsx index fe17ba083..9e34fb646 100644 --- a/docsrc/content/abstraction-comonad.fsx +++ b/docsrc/content/abstraction-comonad.fsx @@ -66,6 +66,7 @@ From .Net/F# - ``Lazy<'T>`` - ``Id<'T>`` - ``('W * 'T)`` + - ``struct ('W * 'T)`` - ``'Monoid -> 'T`` diff --git a/docsrc/content/abstraction-functor.fsx b/docsrc/content/abstraction-functor.fsx index 1ffc1a06e..0dda4997f 100644 --- a/docsrc/content/abstraction-functor.fsx +++ b/docsrc/content/abstraction-functor.fsx @@ -56,6 +56,7 @@ From F# - ``KeyValuePair<'Key,'T>`` - ``Map<'Key,'T>`` - ``'Monoid * 'T`` + - ``'struct ('Monoid * 'T)`` - ``Task<'T>`` - ``'R->'T`` - ``Expr<'T>`` diff --git a/docsrc/content/abstraction-monad.fsx b/docsrc/content/abstraction-monad.fsx index f006db275..58c0284ba 100644 --- a/docsrc/content/abstraction-monad.fsx +++ b/docsrc/content/abstraction-monad.fsx @@ -73,6 +73,7 @@ From F# - ``Result<'T,'U>`` - ``Choice<'T,'U>`` - ``'Monoid * 'T`` + - ``struct ('Monoid * 'T)`` - ``Task<'T>`` - ``'R->'T`` - ``ResizeArray<'T>`` diff --git a/docsrc/content/abstraction-semigroup.fsx b/docsrc/content/abstraction-semigroup.fsx index 5926b8cf0..744e98408 100644 --- a/docsrc/content/abstraction-semigroup.fsx +++ b/docsrc/content/abstraction-semigroup.fsx @@ -42,6 +42,7 @@ From .Net/F# - ``Map<'T,'U>`` - ``TimeSpan`` - ``Tuple<*>`` + - ``ValueTuple<*> ( * up to 7 elements)`` - ``'T1* ... *'Tn`` - ``Task<'T>`` - ``'T->'Semigroup`` diff --git a/src/FSharpPlus/Control/Applicative.fs b/src/FSharpPlus/Control/Applicative.fs index 400a3cef6..9cd0a48e7 100644 --- a/src/FSharpPlus/Control/Applicative.fs +++ b/src/FSharpPlus/Control/Applicative.fs @@ -27,6 +27,7 @@ type Apply = static member ``<*>`` (f: _ [] , x: 'T [] , []_output: 'U [] , []_mthd: Apply) = Array.apply f x : 'U [] static member ``<*>`` (f: 'r -> _ , g: _ -> 'T , []_output: 'r -> 'U , []_mthd: Apply) = fun x -> let f' = f x in f' (g x) : 'U static member inline ``<*>`` ((a: 'Monoid, f) , (b: 'Monoid, x: 'T) , []_output: 'Monoid * 'U , []_mthd: Apply) = (Plus.Invoke a b, f x) : 'Monoid *'U + static member inline ``<*>`` (struct (a: 'Monoid, f), struct (b: 'Monoid, x: 'T), []_output: struct ('Monoid * 'U), []_mthd: Apply) = struct (Plus.Invoke a b, f x) : struct ('Monoid * 'U) #if !FABLE_COMPILER static member ``<*>`` (f: Task<_> , x: Task<'T> , []_output: Task<'U> , []_mthd: Apply) = Task.apply f x : Task<'U> #endif @@ -78,6 +79,7 @@ type Lift2 = static member Lift2 (f, (x , y ), _mthd: Lift2) = Array.lift2 f x y static member Lift2 (f, (x: 'R -> 'T , y: 'R -> 'U ), _mthd: Lift2) = fun a -> f (x a) (y a) static member inline Lift2 (f, ((a: 'Monoid, x: 'T) , (b: 'Monoid, y: 'U) ), _mthd: Lift2) = Plus.Invoke a b, f x y + static member inline Lift2 (f, (struct (a: 'Monoid, x: 'T), struct (b: 'Monoid, y: 'U)), _mthd: Lift2) = struct (Plus.Invoke a b, f x y) #if !FABLE_COMPILER static member Lift2 (f, (x: Task<'T> , y: Task<'U> ), _mthd: Lift2) = Task.map2 f x y #endif diff --git a/src/FSharpPlus/Control/Bifoldable.fs b/src/FSharpPlus/Control/Bifoldable.fs index 97749dd23..e6d746b2f 100644 --- a/src/FSharpPlus/Control/Bifoldable.fs +++ b/src/FSharpPlus/Control/Bifoldable.fs @@ -12,6 +12,7 @@ type BifoldMap = static member BifoldMap (x: Result<'T2,'T1>, f, g, _impl: BifoldMap) = match x with Error x -> f x | Ok x -> g x : 'U static member BifoldMap (x: Choice<'T2,'T1>, f, g, _impl: BifoldMap) = match x with Choice2Of2 x -> f x | Choice1Of2 x -> g x : 'U static member inline BifoldMap ((x: 'T1, y: 'T2) , f, g, _impl: BifoldMap) = Plus.Invoke (f x) (g y) : 'U + static member inline BifoldMap (struct (x: 'T1, y: 'T2), f, g, _impl: BifoldMap) = Plus.Invoke (f x) (g y) : 'U static member inline Invoke (f: 'T1->'U) (g: 'T2->'U) (source: '``Bifoldable``) : 'U = let inline call (a: ^a, b: ^b) = ((^a or ^b) : (static member BifoldMap : _*_*_*_ -> _) b,f,g,a) @@ -30,6 +31,7 @@ type Bifold = static member inline Bifold (x: Result<'T2,'T1>, f: 'S->'T1->'S, g : 'S->'T2->'S, z: 'S, _impl: Bifold) = match x with Error x -> f z x | Ok x -> g z x static member inline Bifold (x: Choice<'T2,'T1>, f: 'S->'T1->'S, g : 'S->'T2->'S, z: 'S, _impl: Bifold) = match x with Choice2Of2 x -> f z x | Choice1Of2 x -> g z x static member inline Bifold ((x: 'T1, y: 'T2) , f: 'S->'T1->'S, g : 'S->'T2->'S, z: 'S, _impl: Bifold) = g (f z x) y + static member inline Bifold (struct (x: 'T1, y: 'T2), f: 'S -> 'T1 -> 'S, g : 'S -> 'T2 -> 'S, z: 'S, _impl: Bifold) = g (f z x) y static member inline Invoke (f: 'S->'T1->'S) (g: 'S->'T2->'S) (z: 'S) (source: '``Bifoldable<'T1,'T2>``) : 'S = let inline call (a: ^a, b: ^b) = ((^a or ^b) : (static member Bifold : _*_*_*_*_ -> _) b,f,g,z,a) @@ -48,6 +50,7 @@ type BifoldBack = static member inline BifoldBack (x: Result<'T2,'T1>, f: 'T1->'S->'S, g : 'T2->'S->'S, z: 'S, _impl: BifoldBack) = match x with Error x -> f x z | Ok x -> g x z static member inline BifoldBack (x: Choice<'T2,'T1>, f: 'T1->'S->'S, g : 'T2->'S->'S, z: 'S, _impl: BifoldBack) = match x with Choice2Of2 x -> f x z | Choice1Of2 x -> g x z static member inline BifoldBack ((x: 'T1, y: 'T2) , f: 'T1->'S->'S, g : 'T2->'S->'S, z: 'S, _impl: BifoldBack) = (f x (g y z)) + static member inline BifoldBack (struct (x: 'T1, y: 'T2), f: 'T1 -> 'S -> 'S, g : 'T2 -> 'S -> 'S, z: 'S, _impl: BifoldBack) = (f x (g y z)) static member inline Invoke (f: 'T1->'S->'S) (g: 'T2->'S->'S) (z: 'S) (source: '``Bifoldable<'T1,'T2>``) : 'S = let inline call (a: ^a, b: ^b) = ((^a or ^b) : (static member BifoldBack : _*_*_*_*_ -> _) b,f,g,z,a) @@ -66,6 +69,7 @@ type Bisum = static member Bisum (x: Result<_,_>, _impl: Bisum) = match x with Ok x -> x | Error x -> x static member Bisum (x: Choice<_,_>, _impl: Bisum) = match x with Choice1Of2 x -> x | Choice2Of2 x -> x static member inline Bisum ((x,y) , _impl: Bisum) = Plus.Invoke x y + static member inline Bisum (struct (x, y) , _impl: Bisum) = Plus.Invoke x y static member inline Invoke (source: '``Bifoldable<'T1,'T2>``) : 'U = let inline call (a: ^a, b: ^b) = ((^a or ^b) : (static member Bisum : _*_ -> _) b,a) diff --git a/src/FSharpPlus/Control/Bitraversable.fs b/src/FSharpPlus/Control/Bitraversable.fs index f75099d1d..2157044ed 100644 --- a/src/FSharpPlus/Control/Bitraversable.fs +++ b/src/FSharpPlus/Control/Bitraversable.fs @@ -13,6 +13,7 @@ type Bitraverse = static member inline Bitraverse (x: Choice<'T1,'Error1>, f: 'Error1->'``Functor<'Error2>``, g: 'T1->'``Functor<'T2>``, _impl: Bitraverse) : '``Functor>`` = match x with Choice1Of2 a -> Map.Invoke Choice<'Error2,'T2>.Choice1Of2 (g a) | Choice2Of2 e -> Map.Invoke Choice<'Error2,'T2>.Choice2Of2 (f e) static member inline Bitraverse ((x: 'T1, y: 'U1), f: 'T1->'``Functor<'T2>``, g: 'U1->'``Functor<'U2>``, _impl: Bitraverse) : '``Functor<'T2 * 'U2>`` = Lift2.Invoke (fun a b -> (a, b)) (f x) (g y) + static member inline Bitraverse (struct (x: 'T1, y: 'U1), f: 'T1->'``Functor<'T2>``, g: 'U1->'``Functor<'U2>``, _impl: Bitraverse) : '``Functor`` = Lift2.Invoke (fun (a: 'T) (b: 'U) -> struct (a, b)) (f x) (g y) static member inline Invoke (f: 'T1->'``Functor<'T2>``) (g: 'U1->'``Functor<'U2>``) (source: '``Bitraversable<'T1,'U1>``) : '``Functor<'Bitraversable<'T2,'U2>>`` = let inline call (a: ^a, b: ^b, _: 'r) = ((^a or ^b or ^r) : (static member Bitraverse : _*_*_*_ -> _) b,f,g,a) @@ -30,6 +31,7 @@ type Bisequence = static member inline Bisequence (x: Choice<'``Functor<'Error>``, '``Functor<'T>``>, _impl: Bisequence) : '``Functor>`` = match x with Choice1Of2 a -> Map.Invoke Choice<'Error,'T>.Choice1Of2 a | Choice2Of2 e -> Map.Invoke Choice<'Error,'T>.Choice2Of2 e static member inline Bisequence ((x: '``Functor<'T>``, y: '``Functor<'U>``), _impl: Bisequence) : '``Functor<'T2 * 'U>`` = Lift2.Invoke (fun a b -> (a, b)) x y + static member inline Bisequence (struct (x: '``Functor<'T>``, y: '``Functor<'U>``), _impl: Bisequence) : '``Functor`` = Lift2.Invoke (fun a b -> struct (a, b)) x y static member inline Invoke (source: '``Bitraversable<'Functor<'T>,'Functor<'U>>``) : '``Functor<'Bitraversable<'T,'U>>`` = let inline call (a: ^a, b: ^b, _: 'r) = ((^a or ^b or ^r) : (static member Bisequence : _*_ -> _) b, a) diff --git a/src/FSharpPlus/Control/Comonad.fs b/src/FSharpPlus/Control/Comonad.fs index 1736a9be7..148784b5d 100644 --- a/src/FSharpPlus/Control/Comonad.fs +++ b/src/FSharpPlus/Control/Comonad.fs @@ -18,7 +18,8 @@ type Extract = Async.StartImmediateAsTask(x).Result #endif static member Extract (x: Lazy<'T> ) = x.Value - static member Extract ((_: 'W, a: 'T) ) = a + static member Extract ((_: 'W, a: 'T) ) = a + static member Extract (struct (_: 'W, a: 'T)) = a static member Extract (f: 'T Id ) = f #if !FABLE_COMPILER || FABLE_COMPILER_3 static member inline Extract (f: 'Monoid -> 'T) = f (Zero.Invoke ()) @@ -36,6 +37,7 @@ type Extend = static member (=>>) (g: Async<'T> , f: Async<'T> -> 'U) = async.Return (f g) : Async<'U> static member (=>>) (g: Lazy<'T> , f: Lazy<'T> -> 'U ) = Lazy<_>.Create (fun () -> f g) : Lazy<'U> static member (=>>) ((w: 'W, a: 'T) , f: _ -> 'U ) = (w, f (w, a)) + static member (=>>) (struct (w: 'W, a: 'T), f: _ -> 'U ) = struct (w, f (struct (w, a))) static member (=>>) (g: Id<'T> , f: Id<'T> -> 'U ) = f g #if !FABLE_COMPILER || FABLE_COMPILER_3 static member inline (=>>) (g: 'Monoid -> 'T, f: _ -> 'U ) = fun a -> f (fun b -> g (Plus.Invoke a b)) @@ -79,6 +81,7 @@ type Duplicate = static member Duplicate (s: Lazy<'T> , []_mthd: Duplicate) = Lazy<_>.CreateFromValue s : Lazy> static member Duplicate (s: Id<'T> , []_mthd: Duplicate) = Id s : Id> static member Duplicate ((w: 'W, a: 'T) , []_mthd: Duplicate) = w, (w, a) + static member Duplicate (struct (w: 'W, a: 'T), []_mthd: Duplicate) = struct (w, struct (w, a)) static member inline Duplicate (f: 'Monoid -> 'T , []_mthd: Duplicate) = fun a b -> f (Plus.Invoke a b) // Restricted Comonads diff --git a/src/FSharpPlus/Control/Functor.fs b/src/FSharpPlus/Control/Functor.fs index b412e3898..d82a0d77d 100644 --- a/src/FSharpPlus/Control/Functor.fs +++ b/src/FSharpPlus/Control/Functor.fs @@ -71,6 +71,7 @@ type Map = static member Map ((g: 'R->'T , f: 'T->'U), _mthd: Map) = (>>) g f static member Map ((g: Func<'R, 'T> , f: 'T->'U), _mthd: Map) = Func<'R, 'U> (g.Invoke >> f) static member Map (((m: 'Monoid, a) , f: 'T->'U), _mthd: Map) = (m, f a) + static member Map ((struct (m: 'Monoid, a) , f: 'T->'U), _mthd: Map) = struct (m, f a) static member Map ((x: _ [] , f: 'T->'U), _mthd: Map) = Array.map f x #if !FABLE_COMPILER static member Map ((x: _ [,] , f: 'T->'U), _mthd: Map) = Array2D.map f x @@ -150,6 +151,7 @@ type Unzip = static member Unzip ((source: 'R -> ('T * 'U) , _output: ('R -> 'T) * ('R -> 'U) ) , _mthd: Unzip ) = (fun x -> fst (source x)), (fun x -> snd (source x)) static member Unzip ((source: Func<'R, ('T * 'U)> , _output: Func<'R,'T> * Func<'R,'U> ) , _mthd: Unzip ) = Func<_,_> (fun x -> fst (source.Invoke x)), Func<_,_> (fun x -> snd (source.Invoke x)) static member Unzip (((m: 'Monoid, t: ('T * 'U)) , _output: ('Monoid * 'T) * ('Monoid * 'U) ) , _mthd: Unzip ) = (m, fst t), (m, snd t) + static member Unzip ((struct (m: 'Monoid, t: ('T * 'U)) , _output: struct ('Monoid * 'T) * struct ('Monoid * 'U) ) , _mthd: Unzip ) = struct (m, fst t), struct (m, snd t) static member Unzip ((source: ('T * 'U) [] , _output: 'T [] * 'U [] ) , _mthd: Unzip ) = Array.unzip source #if !FABLE_COMPILER static member Unzip ((source: ('T * 'U) [,] , _output: 'T [,] * 'U [,] ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source @@ -230,6 +232,7 @@ type Bimap = inherit Default1 static member Bimap ((x: 'T1, y: 'T2) , f: 'T1->'U1, g: 'T2->'U2, []_mthd: Bimap) = (f x, g y) + static member Bimap (struct (x: 'T1, y: 'T2), f: 'T1->'U1, g: 'T2->'U2, []_mthd: Bimap) = struct (f x, g y) static member Bimap (x: Result<'T2, 'T1> , f: 'T1->'U1, g: 'T2->'U2, []_mthd: Bimap) = Result.either (Ok << g) (Error << f) x static member Bimap (KeyValue(k:'T1, x:'T2), f: 'T1->'U1, g: 'T2->'U2, []_mthd: Bimap) = KeyValuePair (f k, g x) static member Bimap (x: Choice<'T2, 'T1> , f: 'T1->'U1, g: 'T2->'U2, []_mthd: Bimap) = Choice.either (Choice1Of2 << g) (Choice2Of2 << f) x @@ -248,6 +251,7 @@ type MapFirst = inherit Default1 static member First ((x: 'T1, y: 'T2) , f: 'T1->'U1, []_mthd: MapFirst) = (f x, y) + static member First (struct (x: 'T1, y: 'T2) , f: 'T1->'U1, []_mthd: MapFirst) = struct (f x, y) static member First (x: Result<'T2, 'T1> , f: 'T1->'U1, []_mthd: MapFirst) = Result.either Ok (Error << f) x static member First (x: Choice<'T2, 'T1> , f: 'T1->'U1, []_mthd: MapFirst) = Choice.either Choice1Of2 (Choice2Of2 << f) x static member First (KeyValue(k: 'T1, x: 'T2), f: 'T1->'U1, []_mthd: MapFirst) = KeyValuePair (f k, x) diff --git a/src/FSharpPlus/Control/Monad.fs b/src/FSharpPlus/Control/Monad.fs index 757ed4ab0..ef5591ea0 100644 --- a/src/FSharpPlus/Control/Monad.fs +++ b/src/FSharpPlus/Control/Monad.fs @@ -28,8 +28,10 @@ type Bind = static member (>>=) (source , k: 'T -> _ ) = (fun r -> k (source r) r) : 'R->'U #if !FABLE_COMPILER static member inline (>>=) ((w: 'Monoid, a: 'T), k: 'T -> 'Monoid * 'U) = let m, b = k a in (Plus.Invoke w m, b) : 'Monoid*'U + static member inline (>>=) (struct (w: 'Monoid, a: 'T), k: 'T -> struct ('Monoid * 'U)) = let struct (m, b) = k a in struct (Plus.Invoke w m, b) : struct ('Monoid * 'U) #else static member inline (>>=) ((w: 'Monoid, a: 'T), k: 'T -> 'Monoid * 'U) = let m, b = k a in (w + m, b) : 'Monoid*'U + static member inline (>>=) (struct (w: 'Monoid, a: 'T), k: 'T -> struct ('Monoid * 'U)) = let struct (m, b) = k a in struct (w + m, b) : struct ('Monoid * 'U) #endif static member (>>=) (source , f: 'T -> _ ) = async.Bind (source, f) : Async<'U> static member (>>=) (source , k: 'T -> _ ) = Result.bind k source : Result<'U,'E> @@ -79,6 +81,7 @@ type Join = static member Join (x: _ [][] , []_output: 'T [] , []_mthd: Join ) = Array.concat x : 'T [] static member Join (g , []_output: 'R->'T , []_mthd: Join ) = (fun r -> (g r) r) : 'R->'T static member inline Join (m1, (m2, x) , []_output: 'Monoid * 'T , []_mthd: Join ) = Plus.Invoke m1 m2, x : 'Monoid*'T + static member inline Join (struct (m1, struct (m2, x)), []_output: struct ('Monoid * 'T), []_mthd: Join) = Plus.Invoke m1 m2, x : struct ('Monoid * 'T) static member Join (x , []_output: Async<'T> , []_mthd: Join ) = async.Bind (x, id) : Async<'T> static member Join (x , []_output: Result<'T,'E> , []_mthd: Join ) = Result.flatten x : Result<'T,'E> static member Join (x , []_output: Choice<'T,'E> , []_mthd: Join ) = Choice.flatten x : Choice<'T,'E> @@ -133,6 +136,7 @@ type Return = static member Return (_: 'a [] , _: Return ) = fun x -> [|x|] : 'a [] static member Return (_: 'r -> 'a , _: Return ) = const': 'a -> 'r -> _ static member inline Return (_: 'm * 'a , _: Return ) = fun (x: 'a) -> (Zero.Invoke (): 'm), x + static member inline Return (_: struct ('m * 'a), _: Return ) = fun (x: 'a) -> struct ((Zero.Invoke (): 'm), x) static member Return (_: 'a Async , _: Return ) = fun (x: 'a) -> async.Return x static member Return (_: Result<'a,'e> , _: Return ) = fun x -> Ok x : Result<'a,'e> static member Return (_: Choice<'a,'e> , _: Return ) = fun x -> Choice1Of2 x : Choice<'a,'e> diff --git a/src/FSharpPlus/Control/Monoid.fs b/src/FSharpPlus/Control/Monoid.fs index 93cfeeaeb..f792ff723 100644 --- a/src/FSharpPlus/Control/Monoid.fs +++ b/src/FSharpPlus/Control/Monoid.fs @@ -95,6 +95,18 @@ type Plus with #endif +#if !FABLE_COMPILER +type Plus with + static member inline ``+`` ( x: ValueTuple<'a> , y: ValueTuple<'a> , []_mthd: Plus) = ValueTuple<'a> (Plus.Invoke x.Item1 y.Item1) : ValueTuple<'a> + static member inline ``+`` (struct (x1,x2 ), struct (y1,y2 ), []_mthd: Plus) = struct (Plus.Invoke x1 y1, Plus.Invoke x2 y2 ) : struct ('a*'b) + static member inline ``+`` (struct (x1,x2,x3 ), struct (y1,y2,y3 ), []_mthd: Plus) = struct (Plus.Invoke x1 y1, Plus.Invoke x2 y2, Plus.Invoke x3 y3 ) : struct ('a*'b*'c) + static member inline ``+`` (struct (x1,x2,x3,x4 ), struct (y1,y2,y3,y4 ), []_mthd: Plus) = struct (Plus.Invoke x1 y1, Plus.Invoke x2 y2, Plus.Invoke x3 y3, Plus.Invoke x4 y4 ) : struct ('a*'b*'c*'d) + static member inline ``+`` (struct (x1,x2,x3,x4,x5 ), struct (y1,y2,y3,y4,y5 ), []_mthd: Plus) = struct (Plus.Invoke x1 y1, Plus.Invoke x2 y2, Plus.Invoke x3 y3, Plus.Invoke x4 y4, Plus.Invoke x5 y5 ) : struct ('a*'b*'c*'d*'e) + static member inline ``+`` (struct (x1,x2,x3,x4,x5,x6 ), struct (y1,y2,y3,y4,y5,y6 ), []_mthd: Plus) = struct (Plus.Invoke x1 y1, Plus.Invoke x2 y2, Plus.Invoke x3 y3, Plus.Invoke x4 y4, Plus.Invoke x5 y5, Plus.Invoke x6 y6 ) : struct ('a*'b*'c*'d*'e*'f) + static member inline ``+`` (struct (x1,x2,x3,x4,x5,x6,x7), struct (y1,y2,y3,y4,y5,y6,y7), []_mthd: Plus) = struct (Plus.Invoke x1 y1, Plus.Invoke x2 y2, Plus.Invoke x3 y3, Plus.Invoke x4 y4, Plus.Invoke x5 y5, Plus.Invoke x6 y6, Plus.Invoke x7 y7) : struct ('a*'b*'c*'d*'e*'f*'g) +#endif + + #if !FABLE_COMPILER type Plus with diff --git a/src/FSharpPlus/Control/Numeric.fs b/src/FSharpPlus/Control/Numeric.fs index f5a18b69c..06a979f22 100644 --- a/src/FSharpPlus/Control/Numeric.fs +++ b/src/FSharpPlus/Control/Numeric.fs @@ -167,6 +167,7 @@ type Zero with type Zero with static member inline Zero (_: Tuple<'a>, _: Zero) = tuple1 (Zero.Invoke ()) : Tuple<'a> static member inline Zero (_: Id<'a> , _: Zero) = Id<_> (Zero.Invoke ()) + static member inline Zero (_: ValueTuple<'a>, _: Zero) = valueTuple1 (Zero.Invoke ()) : ValueTuple<'a> type Zero with static member inline Zero (_: 'a*'b , _: Zero) = (Zero.Invoke (), Zero.Invoke () ) : 'a*'b type Zero with static member inline Zero (_: 'a*'b*'c , _: Zero) = (Zero.Invoke (), Zero.Invoke (), Zero.Invoke () ) : 'a*'b*'c @@ -174,6 +175,14 @@ type Zero with static member inline Zero (_: 'a*'b*'c*'d , _: Zero) = (Z type Zero with static member inline Zero (_: 'a*'b*'c*'d*'e , _: Zero) = (Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke () ) : 'a*'b*'c*'d*'e type Zero with static member inline Zero (_: 'a*'b*'c*'d*'e*'f , _: Zero) = (Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke () ) : 'a*'b*'c*'d*'e*'f type Zero with static member inline Zero (_: 'a*'b*'c*'d*'e*'f*'g, _: Zero) = (Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke ()) : 'a*'b*'c*'d*'e*'f*'g + +type Zero with static member inline Zero (_: ValueTuple<'a,'b> , _: Zero) = ValueTuple.Create (Zero.Invoke (), Zero.Invoke () ) : ValueTuple<'a,'b> +type Zero with static member inline Zero (_: ValueTuple<'a,'b,'c> , _: Zero) = ValueTuple.Create (Zero.Invoke (), Zero.Invoke (), Zero.Invoke () ) : ValueTuple<'a,'b,'c> +type Zero with static member inline Zero (_: ValueTuple<'a,'b,'c,'d> , _: Zero) = ValueTuple.Create (Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke () ) : ValueTuple<'a,'b,'c,'d> +type Zero with static member inline Zero (_: ValueTuple<'a,'b,'c,'d,'e> , _: Zero) = ValueTuple.Create (Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke () ) : ValueTuple<'a,'b,'c,'d,'e> +type Zero with static member inline Zero (_: ValueTuple<'a,'b,'c,'d,'e,'f> , _: Zero) = ValueTuple.Create (Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke () ) : ValueTuple<'a,'b,'c,'d,'e,'f> +type Zero with static member inline Zero (_: ValueTuple<'a,'b,'c,'d,'e,'f,'g>, _: Zero) = ValueTuple.Create (Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke (), Zero.Invoke ()) : ValueTuple<'a,'b,'c,'d,'e,'f,'g> + type Zero with #if !FABLE_COMPILER diff --git a/src/FSharpPlus/Extensions/ValueTuple.fs b/src/FSharpPlus/Extensions/ValueTuple.fs new file mode 100644 index 000000000..d17d916b2 --- /dev/null +++ b/src/FSharpPlus/Extensions/ValueTuple.fs @@ -0,0 +1,14 @@ +namespace FSharpPlus + +/// Additional operations on ValueTuple (,) +[] +module ValueTuple2 = + let mapItem1 f (struct (x, y)) = struct (f x, y) + let mapItem2 f (struct (x, y)) = struct (x, f y) + +/// Additional operations on ValueTuple (,,) +[] +module ValueTuple3 = + let mapItem1 f (struct (x, y, z)) = struct (f x, y, z) + let mapItem2 f (struct (x, y, z)) = struct (x, f y, z) + let mapItem3 f (struct (x, y, z)) = struct (x, y, f z) diff --git a/src/FSharpPlus/FSharpPlus.fsproj b/src/FSharpPlus/FSharpPlus.fsproj index 832af9215..08e453765 100644 --- a/src/FSharpPlus/FSharpPlus.fsproj +++ b/src/FSharpPlus/FSharpPlus.fsproj @@ -51,6 +51,7 @@ + diff --git a/src/FSharpPlus/Internals.fs b/src/FSharpPlus/Internals.fs index 52b48c9fa..7c7fa7108 100644 --- a/src/FSharpPlus/Internals.fs +++ b/src/FSharpPlus/Internals.fs @@ -16,6 +16,8 @@ type Default1 = class inherit Default2 end #nowarn "0042" // retype module internal Prelude = + open System + let inline flip f x y = f y x let inline const' k _ = k let inline tupleToOption x = match x with true, value -> Some value | _ -> None @@ -36,6 +38,8 @@ module internal Prelude = System.Tuple<_> x #endif + let inline valueTuple1<'T1> (t1: 'T1) = ValueTuple.Create t1 + [] module internal Implicit = let inline Invoke (x: ^t) = ((^R or ^t) : (static member op_Implicit : ^t -> ^R) x) : ^R diff --git a/src/FSharpPlus/Operators.fs b/src/FSharpPlus/Operators.fs index ed15d84b0..d5ca08edb 100644 --- a/src/FSharpPlus/Operators.fs +++ b/src/FSharpPlus/Operators.fs @@ -1,5 +1,6 @@ namespace FSharpPlus +open System open FSharpPlus.Control /// Generic functions and operators @@ -114,8 +115,7 @@ module Operators = /// /// Common Combinators let inline tuple8<'T1, 'T2, 'T3, 'T4, 'T5, 'T6, 'T7, 'T8> (t1: 'T1) (t2: 'T2) (t3: 'T3) (t4: 'T4) (t5: 'T5) (t6: 'T6) (t7: 'T7) (t8: 'T8) = t1, t2, t3, t4, t5, t6, t7, t8 - - + #if !FABLE_COMPILER || FABLE_COMPILER_3 // Functor ---------------------------------------------------------------- diff --git a/tests/FSharpPlus.Tests/Monoid.fs b/tests/FSharpPlus.Tests/Monoid.fs index b8c520f0d..512bd84f4 100644 --- a/tests/FSharpPlus.Tests/Monoid.fs +++ b/tests/FSharpPlus.Tests/Monoid.fs @@ -65,4 +65,13 @@ module Monoid = let _arrayGroupAdj = chunkBy ((%)/> 2) [11;2;3;9;5;6;7;8;9;10] - () \ No newline at end of file + () + + [] + let writerMonad () = + let struct (str, num) = monad { + let! x = struct ("Four", 4) + let! y = struct ("Ten", 10) + return y - x } + Assert.AreEqual (str, "FourTen") + Assert.AreEqual (num, 6) \ No newline at end of file