Skip to content

Commit daed63d

Browse files
committed
Add pick related functions to SeqT
1 parent 43050e6 commit daed63d

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

src/FSharpPlus/Data/Seq.fs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,44 @@ module SeqT_V2 =
797797
let inline iteri<'T, .. > (f: int -> 'T -> unit) (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<unit>`` = iteriM (fun i x -> result (f i x)) source
798798
let inline iter<'T, .. > f (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<unit>`` = iterM (f >> result) source
799799

800+
let inline tryPickM<'T, 'U, .. > (f: 'T -> '``Monad<'U option>``) (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<'U option>`` = innerMonad2<_, '``Monad<unit>``> () {
801+
use ie = (source :> IEnumerableM<'``Monad<bool>``, 'T>).GetEnumerator ()
802+
let! (move: bool) = ie.MoveNext ()
803+
let mutable b = move
804+
let mutable res = None
805+
while b && res.IsNone do
806+
let! (fv: 'U option) = f ie.Current
807+
match fv with
808+
| Some _ as r -> res <- r
809+
| None ->
810+
let! moven = ie.MoveNext ()
811+
b <- moven
812+
return res }
813+
814+
let inline pickM<'T, 'U, .. > (f: 'T -> '``Monad<'U option>``) (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<'U>`` =
815+
source |> tryPickM<_, 'U, '``Monad<'U option>``, _, '``Monad<unit>``> f |> Map.Invoke (function Some v -> (v: 'U) | _ -> raise (KeyNotFoundException ()))
816+
817+
let inline tryPick<'T, 'U, .. > (f: 'T -> 'U option) (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<'U option>`` =
818+
tryPickM<_, _, _ , _, '``Monad<unit>``> (f >> Return.Invoke) source
819+
820+
let inline pick (f: 'T -> 'U option) (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<'U>`` =
821+
(source |> tryPick<_, _, _, '``Monad<unit>``, _> f : '``Monad<'U option>``) |> Map.Invoke (function Some v -> (v: 'U) | _ -> raise (KeyNotFoundException ()))
822+
823+
let inline contains value (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<bool>`` =
824+
source |> tryPick<_, _, _, '``Monad<unit>``, '``Monad<unit option>``> (fun v -> if v = value then Some () else None) |> Map.Invoke Option.isSome
825+
826+
let inline tryFind<'T, .. > f (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<'T option>`` =
827+
source |> tryPick<_, _, _, '``Monad<unit>``, _> (fun v -> if f v then Some v else None)
828+
829+
let inline find f (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<'T>`` =
830+
source |> tryFind<_, _, '``Monad<'T option>``, '``Monad<unit>``> f |> Map.Invoke (function Some v -> (v: 'T) | _ -> raise (KeyNotFoundException ()))
831+
832+
let inline exists f (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<bool>`` =
833+
source |> tryFind<_, _, '``Monad<'T option>``, '``Monad<unit>``> f |> Map.Invoke Option.isSome
834+
835+
let inline forall f (source: SeqT<'``Monad<bool>``, 'T>) : '``Monad<bool>`` =
836+
source |> tryFind<_, _, '``Monad<'T option>``, '``Monad<unit>``> (f >> not) |> Map.Invoke Option.isNone
837+
800838
[<RequireQualifiedAccess; EditorBrowsable(EditorBrowsableState.Never)>]
801839
type TryWithState<'``Monad<bool>``, 'T> =
802840
| NotStarted of SeqT<'``Monad<bool>``, 'T>

0 commit comments

Comments
 (0)