Skip to content

Commit 8c5ad63

Browse files
authored
Merge pull request dotnet#1 from liboz/manofstick
Adding ListEnumerable, Choose, and some cleanup
2 parents 42c570c + 9108197 commit 8c5ad63

File tree

1 file changed

+104
-45
lines changed

1 file changed

+104
-45
lines changed

src/fsharp/FSharp.Core/seq.fs

+104-45
Original file line numberDiff line numberDiff line change
@@ -837,21 +837,21 @@ namespace Microsoft.FSharp.Collections
837837

838838
abstract Composer : SeqComponent<'U,'V> -> SeqComponent<'T,'V>
839839

840-
abstract ComposeMap<'S> : Map<'S,'T> -> SeqComponent<'S,'U>
841-
abstract ComposeFilter : Filter<'T> -> SeqComponent<'T,'U>
842-
abstract ComposeFilterMap<'S> : FilterMap<'S,'T> -> SeqComponent<'S,'U>
843-
abstract ComposeMapFilter<'S> : MapFilter<'S,'T> -> SeqComponent<'S,'U>
844-
abstract ComposeSkip : Skip<'T> -> SeqComponent<'T,'U>
840+
abstract ComposeWithMap<'S> : Map<'S,'T> -> SeqComponent<'S,'U>
841+
abstract ComposeWithFilter : Filter<'T> -> SeqComponent<'T,'U>
842+
abstract ComposeWithFilterThenMap<'S> : FilterThenMap<'S,'T> -> SeqComponent<'S,'U>
843+
abstract ComposeWithMapThenFilter<'S> : MapThenFilter<'S,'T> -> SeqComponent<'S,'U>
844+
abstract ComposeWithSkip : Skip<'T> -> SeqComponent<'T,'U>
845845

846846
default __.OnComplete () = ()
847847

848-
default first.Composer (second:SeqComponent<'U,'V>) : SeqComponent<'T,'V> = upcast Composed (first, second)
848+
default first.Composer (second:SeqComponent<'U,'V>) : SeqComponent<'T,'V> = upcast Composed (first, second)
849849

850-
default second.ComposeMap<'S> (first:Map<'S,'T>) : SeqComponent<'S,'U> = upcast Composed (first, second)
851-
default second.ComposeFilter (first:Filter<'T>) : SeqComponent<'T,'U> = upcast Composed (first, second)
852-
default second.ComposeFilterMap<'S> (first:FilterMap<'S,'T>) : SeqComponent<'S,'U> = upcast Composed (first, second)
853-
default second.ComposeMapFilter<'S> (first:MapFilter<'S,'T>) : SeqComponent<'S,'U> = upcast Composed (first, second)
854-
default second.ComposeSkip (first:Skip<'T>) : SeqComponent<'T,'U> = upcast Composed (first, second)
850+
default second.ComposeWithMap<'S> (first:Map<'S,'T>) : SeqComponent<'S,'U> = upcast Composed (first, second)
851+
default second.ComposeWithFilter (first:Filter<'T>) : SeqComponent<'T,'U> = upcast Composed (first, second)
852+
default second.ComposeWithFilterThenMap<'S> (first:FilterThenMap<'S,'T>) : SeqComponent<'S,'U> = upcast Composed (first, second)
853+
default second.ComposeWithMapThenFilter<'S> (first:MapThenFilter<'S,'T>) : SeqComponent<'S,'U> = upcast Composed (first, second)
854+
default second.ComposeWithSkip (first:Skip<'T>) : SeqComponent<'T,'U> = upcast Composed (first, second)
855855

856856
and Composed<'T,'U,'V> (first:SeqComponent<'T,'U>, second:SeqComponent<'U,'V>) =
857857
inherit SeqComponent<'T,'V>()
@@ -874,16 +874,16 @@ namespace Microsoft.FSharp.Collections
874874
inherit SeqComponent<'T,'U>()
875875

876876
override first.Composer (second:SeqComponent<'U,'V>) : SeqComponent<'T,'V> =
877-
second.ComposeMap first
877+
second.ComposeWithMap first
878878

879-
override second.ComposeMap<'S> (first:Map<'S,'T>) : SeqComponent<'S,'U> =
879+
override second.ComposeWithMap<'S> (first:Map<'S,'T>) : SeqComponent<'S,'U> =
880880
upcast Map (first.Map >> second.Map)
881881

882-
override second.ComposeFilter (first:Filter<'T>) : SeqComponent<'T,'U> =
883-
upcast FilterMap (first.Filter, second.Map)
882+
override second.ComposeWithFilter (first:Filter<'T>) : SeqComponent<'T,'U> =
883+
upcast FilterThenMap (first.Filter, second.Map)
884884

885-
override second.ComposeFilterMap<'S> (first:FilterMap<'S,'T>) : SeqComponent<'S,'U> =
886-
upcast FilterMap (first.Filter, first.Map >> second.Map)
885+
override second.ComposeWithFilterThenMap<'S> (first:FilterThenMap<'S,'T>) : SeqComponent<'S,'U> =
886+
upcast FilterThenMap (first.Filter, first.Map >> second.Map)
887887

888888
override __.ProcessNext (input:'T, halted:byref<bool>, output:byref<'U>) : bool =
889889
output <- map input
@@ -906,17 +906,17 @@ namespace Microsoft.FSharp.Collections
906906
and Filter<'T> (filter:'T->bool) =
907907
inherit SeqComponent<'T,'T>()
908908

909-
override this.Composer (next:SeqComponent<'T,'V>) : SeqComponent<'T,'V> =
910-
next.ComposeFilter this
909+
override first.Composer (second:SeqComponent<'T,'V>) : SeqComponent<'T,'V> =
910+
second.ComposeWithFilter first
911911

912-
override second.ComposeMap<'S> (first:Map<'S,'T>) : SeqComponent<'S,'T> =
913-
upcast MapFilter (first.Map, second.Filter)
912+
override second.ComposeWithMap<'S> (first:Map<'S,'T>) : SeqComponent<'S,'T> =
913+
upcast MapThenFilter (first.Map, second.Filter)
914914

915-
override second.ComposeFilter (first:Filter<'T>) : SeqComponent<'T,'T> =
915+
override second.ComposeWithFilter (first:Filter<'T>) : SeqComponent<'T,'T> =
916916
upcast Filter (Helpers.ComposeFilter first.Filter second.Filter)
917917

918-
override second.ComposeMapFilter<'S> (first:MapFilter<'S,'T>) : SeqComponent<'S,'T> =
919-
upcast MapFilter (first.Map, Helpers.ComposeFilter first.Filter second.Filter)
918+
override second.ComposeWithMapThenFilter<'S> (first:MapThenFilter<'S,'T>) : SeqComponent<'S,'T> =
919+
upcast MapThenFilter (first.Map, Helpers.ComposeFilter first.Filter second.Filter)
920920

921921
override __.ProcessNext (input:'T, halted:byref<bool>, output:byref<'T>) : bool =
922922
if filter input then
@@ -927,20 +927,20 @@ namespace Microsoft.FSharp.Collections
927927

928928
member __.Filter :'T->bool = filter
929929

930-
and MapFilter<'T,'U> (map:'T->'U, filter:'U->bool) =
930+
and MapThenFilter<'T,'U> (map:'T->'U, filter:'U->bool) =
931931
inherit SeqComponent<'T,'U>()
932932

933933
override __.ProcessNext (input:'T, halted:byref<bool>, output:byref<'U>) :bool =
934934
output <- map input
935935
Helpers.avoidTailCall (filter output)
936936

937937
override first.Composer (second:SeqComponent<'U,'V>):SeqComponent<'T,'V> =
938-
second.ComposeMapFilter first
938+
second.ComposeWithMapThenFilter first
939939

940940
member __.Map : 'T->'U = map
941941
member __.Filter : 'U->bool = filter
942942

943-
and FilterMap<'T,'U> (filter:'T->bool, map:'T->'U) =
943+
and FilterThenMap<'T,'U> (filter:'T->bool, map:'T->'U) =
944944
inherit SeqComponent<'T,'U>()
945945

946946
override __.ProcessNext (input:'T, halted:byref<bool>, output:byref<'U>) : bool =
@@ -950,7 +950,7 @@ namespace Microsoft.FSharp.Collections
950950
else
951951
false
952952

953-
override this.Composer (next:SeqComponent<'U,'V>) : SeqComponent<'T,'V> = next.ComposeFilterMap this
953+
override first.Composer (second:SeqComponent<'U,'V>) : SeqComponent<'T,'V> = second.ComposeWithFilterThenMap first
954954

955955
member __.Filter : 'T->bool = filter
956956
member __.Map : 'T->'U = map
@@ -977,10 +977,10 @@ namespace Microsoft.FSharp.Collections
977977
let mutable count = 0
978978

979979
override first.Composer (second:SeqComponent<'T,'V>) : SeqComponent<'T,'V> =
980-
second.ComposeSkip first
980+
second.ComposeWithSkip first
981981

982-
override second.ComposeSkip (first:Skip<'T>) : SeqComponent<'T,'T> =
983-
if System.Int32.MaxValue - second.SkipCount > first.SkipCount then
982+
override second.ComposeWithSkip (first:Skip<'T>) : SeqComponent<'T,'T> =
983+
if Int32.MaxValue - first.SkipCount - second.SkipCount > 0 then
984984
upcast Skip (first.SkipCount + second.SkipCount)
985985
else
986986
upcast Composed (first, second)
@@ -1006,9 +1006,9 @@ namespace Microsoft.FSharp.Collections
10061006

10071007
let mutable count = 0
10081008

1009-
override second.ComposeSkip (first:Skip<'T>) : SeqComponent<'T,'T> =
1010-
if System.Int32.MaxValue - second.TakeCount > first.SkipCount then
1011-
upcast SkipTake (first.SkipCount, first.SkipCount+second.TakeCount)
1009+
override second.ComposeWithSkip (first:Skip<'T>) : SeqComponent<'T,'T> =
1010+
if Int32.MaxValue - first.SkipCount - second.TakeCount > 0 then
1011+
upcast SkipThenTake (first.SkipCount, first.SkipCount+second.TakeCount)
10121012
else
10131013
upcast Composed (first, second)
10141014

@@ -1030,7 +1030,7 @@ namespace Microsoft.FSharp.Collections
10301030

10311031
member __.TakeCount = takeCount
10321032

1033-
and SkipTake<'T> (startIdx:int, endIdx:int) =
1033+
and SkipThenTake<'T> (startIdx:int, endIdx:int) =
10341034
inherit SeqComponent<'T,'T>()
10351035

10361036
let mutable count = 0
@@ -1057,13 +1057,22 @@ namespace Microsoft.FSharp.Collections
10571057
let x = endIdx - count
10581058
invalidOpFmt "tried to take {0} {1} past the end of the seq"
10591059
[|SR.GetString SR.notEnoughElements; x; (if x=1 then "element" else "elements")|]
1060+
1061+
and Choose<'T, 'U> (choose:'T->'U option) =
1062+
inherit SeqComponent<'T,'U>()
1063+
1064+
override __.ProcessNext (input:'T, halted:byref<bool>, output:byref<'U>) : bool =
1065+
match choose input with
1066+
| Some value -> output <- value
1067+
true
1068+
| None -> false
10601069

10611070
type SeqProcessNextStates =
10621071
| NotStarted = 1
10631072
| Finished = 2
10641073
| InProcess = 3
10651074

1066-
type SeqEnumeratorEnumerator<'T,'U>(enumerator:IEnumerator<'T>, t2u:SeqComponent<'T,'U>) =
1075+
type SeqComposedEnumerator<'T,'U>(enumerator:IEnumerator<'T>, t2u:SeqComponent<'T,'U>) =
10671076
let mutable state = SeqProcessNextStates.NotStarted
10681077
let mutable current = Unchecked.defaultof<'U>
10691078
let mutable halted = false
@@ -1082,7 +1091,7 @@ namespace Microsoft.FSharp.Collections
10821091
false
10831092

10841093
interface IDisposable with
1085-
member x.Dispose():unit =
1094+
member __.Dispose():unit =
10861095
match source with
10871096
| null -> ()
10881097
| _ -> source.Dispose (); source <- Unchecked.defaultof<_>
@@ -1095,13 +1104,13 @@ namespace Microsoft.FSharp.Collections
10951104
member __.Reset () : unit = noReset ()
10961105

10971106
interface IEnumerator<'U> with
1098-
member x.Current =
1107+
member __.Current =
10991108
match state with
11001109
| SeqProcessNextStates.NotStarted -> notStarted()
11011110
| SeqProcessNextStates.Finished -> alreadyFinished()
11021111
| _ -> current
11031112

1104-
type SeqArrayEnumerator<'T,'U>(array:array<'T>, t2u:SeqComponent<'T,'U>) =
1113+
type ArrayComposedEnumerator<'T,'U>(array:array<'T>, t2u:SeqComponent<'T,'U>) =
11051114
let mutable state = SeqProcessNextStates.NotStarted
11061115
let mutable current = Unchecked.defaultof<'U>
11071116
let mutable halted = false
@@ -1121,7 +1130,7 @@ namespace Microsoft.FSharp.Collections
11211130
false
11221131

11231132
interface IDisposable with
1124-
member x.Dispose() : unit = ()
1133+
member __.Dispose() : unit = ()
11251134

11261135
interface IEnumerator with
11271136
member this.Current : obj = box ((Helpers.UpcastEnumerator this)).Current
@@ -1131,7 +1140,43 @@ namespace Microsoft.FSharp.Collections
11311140
member __.Reset () : unit = noReset ()
11321141

11331142
interface IEnumerator<'U> with
1134-
member x.Current =
1143+
member __.Current =
1144+
match state with
1145+
| SeqProcessNextStates.NotStarted -> notStarted()
1146+
| SeqProcessNextStates.Finished -> alreadyFinished()
1147+
| _ -> current
1148+
1149+
type ListComposedEnumerator<'T,'U>(alist:list<'T>, t2u:SeqComponent<'T,'U>) =
1150+
let mutable state = SeqProcessNextStates.NotStarted
1151+
let mutable current = Unchecked.defaultof<'U>
1152+
let mutable halted = false
1153+
1154+
let mutable list = alist
1155+
1156+
let rec moveNext () =
1157+
match halted, list with
1158+
| false, head::tail ->
1159+
list <- tail
1160+
if t2u.ProcessNext (head, &halted, &current) then
1161+
true
1162+
else
1163+
moveNext ()
1164+
| _ -> state <- SeqProcessNextStates.Finished
1165+
t2u.OnComplete ()
1166+
false
1167+
1168+
interface IDisposable with
1169+
member __.Dispose() : unit = ()
1170+
1171+
interface IEnumerator with
1172+
member this.Current : obj = box (this:>IEnumerator<'U>).Current
1173+
member __.MoveNext () =
1174+
state <- SeqProcessNextStates.InProcess
1175+
moveNext ()
1176+
member __.Reset () : unit = noReset ()
1177+
1178+
interface IEnumerator<'U> with
1179+
member __.Current =
11351180
match state with
11361181
| SeqProcessNextStates.NotStarted -> notStarted()
11371182
| SeqProcessNextStates.Finished -> alreadyFinished()
@@ -1145,7 +1190,7 @@ namespace Microsoft.FSharp.Collections
11451190
inherit ComposableEnumerable<'U>()
11461191

11471192
let getEnumerator () : IEnumerator<'U> =
1148-
Helpers.UpcastEnumerator (new SeqEnumeratorEnumerator<'T,'U>(enumerable.GetEnumerator(), current ()))
1193+
Helpers.UpcastEnumerator (new SeqComposedEnumerator<'T,'U>(enumerable.GetEnumerator(), current ()))
11491194

11501195
interface IEnumerable with
11511196
member this.GetEnumerator () : IEnumerator = Helpers.UpcastEnumeratorNonGeneric (getEnumerator ())
@@ -1176,7 +1221,7 @@ namespace Microsoft.FSharp.Collections
11761221
inherit ComposableEnumerable<'U>()
11771222

11781223
let getEnumerator () : IEnumerator<'U> =
1179-
Helpers.UpcastEnumerator (new SeqArrayEnumerator<'T,'U>(array, current ()))
1224+
Helpers.UpcastEnumerator (new ArrayComposedEnumerator<'T,'U>(array, current ()))
11801225

11811226
interface IEnumerable with
11821227
member this.GetEnumerator () : IEnumerator = Helpers.UpcastEnumeratorNonGeneric (getEnumerator ())
@@ -1204,6 +1249,20 @@ namespace Microsoft.FSharp.Collections
12041249
//
12051250
// state
12061251

1252+
type SeqListEnumerable<'T,'U>(alist:list<'T>, current:unit->SeqComponent<'T,'U>) =
1253+
inherit ComposableEnumerable<'U>()
1254+
1255+
let getEnumerator () : IEnumerator<'U> =
1256+
Helpers.UpcastEnumerator (new ListComposedEnumerator<'T,'U>(alist, current ()))
1257+
1258+
interface IEnumerable with
1259+
member this.GetEnumerator () : IEnumerator = Helpers.UpcastEnumeratorNonGeneric (getEnumerator ())
1260+
1261+
interface IEnumerable<'U> with
1262+
member this.GetEnumerator () : IEnumerator<'U> = getEnumerator ()
1263+
1264+
override __.Compose (next:unit->SeqComponent<'U,'V>) : IEnumerable<'V> =
1265+
Helpers.UpcastEnumerable (new SeqListEnumerable<'T,'V>(alist, fun () -> (current ()).Composer (next ())))
12071266

12081267

12091268
#if FX_NO_ICLONEABLE
@@ -1330,6 +1389,7 @@ namespace Microsoft.FSharp.Collections
13301389
match source with
13311390
| :? SeqComposer.ComposableEnumerable<'T> as s -> s.Compose createSeqComponent
13321391
| :? array<'T> as a -> SeqComposer.Helpers.UpcastEnumerable (new SeqComposer.SeqArrayEnumerable<_,_>(a, createSeqComponent))
1392+
| :? list<'T> as a -> SeqComposer.Helpers.UpcastEnumerable (new SeqComposer.SeqListEnumerable<_,_>(a, createSeqComponent))
13331393
| _ -> SeqComposer.Helpers.UpcastEnumerable (new SeqComposer.SeqEnumerable<_,_>(source, createSeqComponent))
13341394

13351395
let private seqFactoryForImmutable seqComponent (source:seq<'T>) =
@@ -1371,8 +1431,7 @@ namespace Microsoft.FSharp.Collections
13711431

13721432
[<CompiledName("Choose")>]
13731433
let choose f source =
1374-
checkNonNull "source" source
1375-
revamp (IEnumerator.choose f) source
1434+
source |> seqFactoryForImmutable (SeqComposer.Choose f)
13761435

13771436
[<CompiledName("Indexed")>]
13781437
let indexed source =

0 commit comments

Comments
 (0)