Skip to content

Commit

Permalink
Use new [Option|ValueOption|Result|Choice].Sequence
Browse files Browse the repository at this point in the history
  • Loading branch information
fcallejon committed Nov 15, 2023
1 parent 4f86938 commit 414966a
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 20 deletions.
2 changes: 1 addition & 1 deletion DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ We should add as much concrete implementations for primitive types (types coming

#### Defaults

The goal of default implementations is to allow users of the library to write less code, as an example we expect the user will add `Bind` , `Return` to their specific monad types, but we don't want to force him to add `Join` although if he adds it, code might be more efficient.
The goal of default implementations is to allow users of the library to write less code, as an example we expect the user will add `Bind` , `Return` to their specific monad types, but we don't want to force them to add `Join` although if they do, code might be more efficient.
But those defaults are not intended to be used by developers of F#+ as we should afford writing more code in order to maximize usability of the library. You can read this as "the principle is to allow user to write less boilerplate, and because of that we have to put some boilerplate inside F#+".

#### Invoker
Expand Down
34 changes: 16 additions & 18 deletions src/FSharpPlus/Control/Traversable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,20 @@ open FSharpPlus.Internals.Prelude
open FSharpPlus.Internals.MonadOps
open FSharpPlus.Extensions


type Sequence =
inherit Default1
static member inline InvokeOnInstance (t: '``Traversable<Functor<'T>>``) = (^``Traversable<Functor<'T>>`` : (static member Sequence : _ -> _) t) : '``Functor<'Traversable<'T>>``

[<EditorBrowsable(EditorBrowsableState.Never)>]
static member inline ForInfiniteSequences (t: seq<_>, isFailure, conversion) =
let add x y = y :: x
let mutable go = true
let mutable r = result []
use e = t.GetEnumerator ()
while go && e.MoveNext () do
if isFailure e.Current then go <- false
r <- Map.Invoke add r <*> e.Current
Map.Invoke (List.rev >> conversion) r

let add x y = y :: x
let mutable go = true
let mutable r = result []
use e = t.GetEnumerator ()
while go && e.MoveNext () do
if isFailure e.Current then go <- false
r <- Map.Invoke add r <*> e.Current
Map.Invoke (List.rev >> conversion) r

type Traverse =
inherit Default1
Expand Down Expand Up @@ -187,22 +185,22 @@ type Sequence with
Seq.foldBack cons_f t (result Seq.empty)

static member inline Sequence (t: seq<'``Applicative<'T>``>, [<Optional>]_output: '``Applicative<seq<'T>>`` , [<Optional>]_impl: Default4) = Sequence.ForInfiniteSequences (t, IsLeftZero.Invoke, List.toSeq) : '``Applicative<seq<'T>>``
static member Sequence (t: seq<option<'t>> , [<Optional>]_output: option<seq<'t>> , [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, Option.isNone, List.toSeq) : option<seq<'t>>
static member Sequence (t: seq<option<'t>> , [<Optional>]_output: option<seq<'t>> , [<Optional>]_impl: Default3) = Option.Sequence t : option<seq<'t>>

Check failure on line 188 in src/FSharpPlus/Control/Traversable.fs

View workflow job for this annotation

GitHub Actions / testFable3SubsetOnCore

Type constraint mismatch. The type � ''t array option' �is not compatible with type� 'seq<'t> option'
#if !FABLE_COMPILER
static member Sequence (t: seq<voption<'t>> , [<Optional>]_output: voption<seq<'t>> , [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, ValueOption.isNone, List.toSeq) : voption<seq<'t>>
static member Sequence (t: seq<voption<'t>> , [<Optional>]_output: voption<seq<'t>> , [<Optional>]_impl: Default3) = ValueOption.Sequence t : voption<seq<'t>>
#endif
static member Sequence (t: seq<Result<'t,'e>>, [<Optional>]_output: Result<seq<'t>, 'e>, [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, (function Error _ -> true | _ -> false), List.toSeq) : Result<seq<'t>, 'e>
static member Sequence (t: seq<Choice<'t,'e>>, [<Optional>]_output: Choice<seq<'t>, 'e>, [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, (function Choice2Of2 _ -> true | _ -> false), List.toSeq) : Choice<seq<'t>, 'e>
static member Sequence (t: seq<Result<'t,'e>>, [<Optional>]_output: Result<seq<'t>, 'e>, [<Optional>]_impl: Default3) = Result.Sequence t : Result<seq<'t>, 'e>
static member Sequence (t: seq<Choice<'t,'e>>, [<Optional>]_output: Choice<seq<'t>, 'e>, [<Optional>]_impl: Default3) = Choice.Sequence t : Choice<seq<'t>, 'e>
static member Sequence (t: seq<list<'t>> , [<Optional>]_output: list<seq<'t>> , [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, List.isEmpty, List.toSeq) : list<seq<'t>>
static member Sequence (t: seq<'t []> , [<Optional>]_output: seq<'t> [] , [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, Array.isEmpty, List.toSeq) : seq<'t> []

#if !FABLE_COMPILER
static member Sequence (t: seq<Async<'t>> , [<Optional>]_output: Async<seq<'t>> , [<Optional>]_impl: Default3) = Async.Sequence t : Async<seq<'t>>
#endif
static member inline Sequence (t: NonEmptySeq<'``Applicative<'T>``>, [<Optional>]_output: '``Applicative<NonEmptySeq<'T>>`` , [<Optional>]_impl: Default4) = Sequence.ForInfiniteSequences (t, IsLeftZero.Invoke, NonEmptySeq.ofList) : '``Applicative<NonEmptySeq<'T>>``
static member Sequence (t: NonEmptySeq<option<'t>> , [<Optional>]_output: option<NonEmptySeq<'t>> , [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, Option.isNone, NonEmptySeq.ofList) : option<NonEmptySeq<'t>>
static member Sequence (t: NonEmptySeq<Result<'t,'e>>, [<Optional>]_output: Result<NonEmptySeq<'t>, 'e>, [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, (function Error _ -> true | _ -> false), NonEmptySeq.ofList) : Result<NonEmptySeq<'t>, 'e>
static member Sequence (t: NonEmptySeq<Choice<'t,'e>>, [<Optional>]_output: Choice<NonEmptySeq<'t>, 'e>, [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, (function Choice2Of2 _ -> true | _ -> false), NonEmptySeq.ofList) : Choice<NonEmptySeq<'t>, 'e>
static member Sequence (t: NonEmptySeq<option<'t>> , [<Optional>]_output: option<NonEmptySeq<'t>> , [<Optional>]_impl: Default3) = Option.Sequence t |> Option.map NonEmptySeq.unsafeOfSeq : option<NonEmptySeq<'t>>
static member Sequence (t: NonEmptySeq<Result<'t,'e>>, [<Optional>]_output: Result<NonEmptySeq<'t>, 'e>, [<Optional>]_impl: Default3) = Result.Sequence t |> Result.map NonEmptySeq.unsafeOfSeq : Result<NonEmptySeq<'t>, 'e>
static member Sequence (t: NonEmptySeq<Choice<'t,'e>>, [<Optional>]_output: Choice<NonEmptySeq<'t>, 'e>, [<Optional>]_impl: Default3) = Choice.Sequence t |> Choice.map NonEmptySeq.unsafeOfSeq : Choice<NonEmptySeq<'t>, 'e>
static member Sequence (t: NonEmptySeq<list<'t>> , [<Optional>]_output: list<NonEmptySeq<'t>> , [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, List.isEmpty, NonEmptySeq.ofList) : list<NonEmptySeq<'t>>
static member Sequence (t: NonEmptySeq<'t []> , [<Optional>]_output: NonEmptySeq<'t> [] , [<Optional>]_impl: Default3) = Sequence.ForInfiniteSequences(t, Array.isEmpty, NonEmptySeq.ofList) : NonEmptySeq<'t> []
#if !FABLE_COMPILER
Expand Down
3 changes: 2 additions & 1 deletion src/FSharpPlus/Extensions/Extensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ module Extensions =
if noneFound
then None
else
Some (accumulator.Close () |> Array.toSeq)
let res = accumulator.Close ()
if res.Length = 0 then None else Some res
#endif

type ValueOption<'t> with
Expand Down

0 comments on commit 414966a

Please sign in to comment.