@@ -18,7 +18,7 @@ module SR =
1818type List < 'T when 'T: comparison > =
1919 { head: 'T ; mutable tail: List < 'T > option }
2020
21- static member inline Empty : List < 'T > = { head = Unchecked.defaultof< 'T>; tail = None }
21+ static member inline Empty : 'T list = { head = Unchecked.defaultof< 'T>; tail = None }
2222 static member inline Cons ( x : 'T , xs : 'T list ) = { head = x; tail = Some xs }
2323
2424 static member inline internal ConsNoTail ( x : 'T ) = { head = x; tail = None }
@@ -176,34 +176,47 @@ let compareWith (comparer: 'T -> 'T -> int) (xs: 'T list) (ys: 'T list): int =
176176 if c = 0 then loop xs.Tail ys.Tail else c
177177 loop xs ys
178178
179+ let toArray ( xs : 'T list ) =
180+ let len = xs.Length
181+ let res = Array.zeroCreate len
182+ let rec loop i ( xs : 'T list ) =
183+ if not xs.IsEmpty then
184+ res.[ i] <- xs.Head
185+ loop ( i + 1 ) xs.Tail
186+ loop 0 xs
187+ res
188+
179189let fold ( folder : 'State -> 'T -> 'State ) ( state : 'State ) ( xs : 'T list ) =
180- let rec loop acc ( ys : 'T list ) =
181- if ys.IsEmpty then acc
182- else loop ( folder acc ys.Head) ys.Tail
183- loop state xs
190+ let mutable acc = state
191+ let mutable xs = xs
192+ while not xs.IsEmpty do
193+ acc <- folder acc xs.Head
194+ xs <- xs.Tail
195+ acc
196+
197+ let reverse ( xs : 'T list ) =
198+ fold ( fun acc x -> List.Cons( x, acc)) List.Empty xs
184199
185200let foldBack ( folder : 'T -> 'State -> 'State ) ( xs : 'T list ) ( state : 'State ) =
186- Seq.foldBack folder xs state
201+ // fold (fun acc x -> folder x acc) state (reverse xs)
202+ Array.foldBack folder ( toArray xs) state
187203
188204let foldIndexed ( folder : int -> 'State -> 'T -> 'State ) ( state : 'State ) ( xs : 'T list ) =
189- let rec loop i acc ( ys : 'T list ) =
190- if ys .IsEmpty then acc
191- else loop ( i + 1 ) ( folder i acc ys .Head) ys .Tail
205+ let rec loop i acc ( xs : 'T list ) =
206+ if xs .IsEmpty then acc
207+ else loop ( i + 1 ) ( folder i acc xs .Head) xs .Tail
192208 loop 0 state xs
193209
194- let reverse ( xs : 'T list ) =
195- fold ( fun acc x -> List.Cons( x, acc)) List.Empty xs
196-
197210let toSeq ( xs : 'T list ): 'T seq =
198211 xs :> System.Collections.Generic.IEnumerable< 'T>
199212
200- let ofArrayWithTail ( xs : System.Collections.Generic.IList < 'T > ) ( tail : 'T list ) =
213+ let ofArrayWithTail ( xs : 'T [] ) ( tail : 'T list ) =
201214 let mutable res = tail
202- for i = xs.Count - 1 downto 0 do
215+ for i = xs.Length - 1 downto 0 do
203216 res <- List.Cons( xs.[ i], res)
204217 res
205218
206- let ofArray ( xs : System.Collections.Generic.IList < 'T > ) =
219+ let ofArray ( xs : 'T [] ) =
207220 ofArrayWithTail xs List.Empty
208221
209222let ofSeq ( xs : seq < 'T >): 'T list =
@@ -212,21 +225,31 @@ let ofSeq (xs: seq<'T>): 'T list =
212225 | :? array< 'T> as arr -> ofArray arr
213226 | _ ->
214227 let root = List.Empty
215- let mutable node = root
216- for x in xs do
217- node <- node.AppendConsNoTail x
228+ let node = Seq.fold ( fun ( acc : 'T list ) x -> acc.AppendConsNoTail x) root xs
218229 node.SetConsTail List.Empty
219230 root.Tail
220231
221232let concat ( lists : seq < 'T list >) =
222- Seq.fold ( fold ( fun acc x -> List.Cons( x, acc))) List.Empty lists
223- |> reverse
233+ let root = List.Empty
234+ let mutable node = root
235+ for xs in lists do
236+ node <- fold ( fun acc x -> acc.AppendConsNoTail x) node xs
237+ node.SetConsTail List.Empty
238+ root.Tail
224239
225- let fold2 f ( state : 'State ) ( xs : 'T list ) ( ys : 'U list ) =
226- Seq.fold2 f state xs ys
240+ let fold2 ( folder : 'State -> 'T1 -> 'T2 -> 'State ) ( state : 'State ) ( xs : 'T1 list ) ( ys : 'T2 list ) =
241+ let mutable acc = state
242+ let mutable xs = xs
243+ let mutable ys = ys
244+ while not xs.IsEmpty && not ys.IsEmpty do
245+ acc <- folder acc xs.Head ys.Head
246+ xs <- xs.Tail
247+ ys <- ys.Tail
248+ acc
227249
228- let foldBack2 f ( xs : 'T list ) ( ys : 'U list ) ( state : 'State ) =
229- Seq.foldBack2 f xs ys state
250+ let foldBack2 ( folder : 'T1 -> 'T2 -> 'State -> 'State ) ( xs : 'T1 list ) ( ys : 'T2 list ) ( state : 'State ) =
251+ // fold2 (fun acc x y -> folder x y acc) state (reverse xs) (reverse ys)
252+ Array.foldBack2 folder ( toArray xs) ( toArray ys) state
230253
231254let unfold ( gen : 'State -> ( 'T * 'State ) option ) ( state : 'State ) =
232255 let rec loop st ( node : 'T list ) =
@@ -237,90 +260,123 @@ let unfold (gen: 'State -> ('T * 'State) option) (state: 'State) =
237260 loop state root
238261 root.Tail
239262
240- let scan f ( state : 'State ) ( xs : 'T list ) =
241- Seq.scan f state xs |> ofSeq
263+ let scan ( folder : 'State -> 'T -> 'State ) ( state : 'State ) ( xs : 'T list ) =
264+ let root = List.Empty
265+ let mutable node = root.AppendConsNoTail state
266+ let mutable acc = state
267+ let mutable xs = xs
268+ while not xs.IsEmpty do
269+ acc <- folder acc xs.Head
270+ node <- node.AppendConsNoTail acc
271+ xs <- xs.Tail
272+ node.SetConsTail List.Empty
273+ root.Tail
242274
243- let scanBack f ( xs : 'T list ) ( state : 'State ) =
244- Seq .scanBack f xs state |> ofSeq
275+ let scanBack ( folder : 'T -> 'State -> 'State ) ( xs : 'T list ) ( state : 'State ) =
276+ Array .scanBack folder ( toArray xs ) state |> ofArray
245277
246278let append ( xs : 'T list ) ( ys : 'T list ) =
247279 fold ( fun acc x -> List.Cons( x, acc)) ys ( reverse xs)
248280
249- let collect ( f : 'T -> 'U list ) ( xs : 'T list ) =
281+ let collect ( mapping : 'T -> 'U list ) ( xs : 'T list ) =
250282 let root = List.Empty
251283 let mutable node = root
252284 let mutable ys = xs
253285 while not ys.IsEmpty do
254- let mutable zs = f ys.Head
286+ let mutable zs = mapping ys.Head
255287 while not zs.IsEmpty do
256288 node <- node.AppendConsNoTail zs.Head
257289 zs <- zs.Tail
258290 ys <- ys.Tail
259291 node.SetConsTail List.Empty
260292 root.Tail
261293
262- let mapIndexed ( f : int -> 'T -> 'U ) ( xs : 'T list ) =
294+ let mapIndexed ( mapping : int -> 'T -> 'U ) ( xs : 'T list ) =
263295 let root = List.Empty
264- let folder i ( acc : 'U list ) x = acc.AppendConsNoTail ( f i x)
296+ let folder i ( acc : 'U list ) x = acc.AppendConsNoTail ( mapping i x)
265297 let node = foldIndexed folder root xs
266298 node.SetConsTail List.Empty
267299 root.Tail
268300
269- let map ( f : 'T -> 'U ) ( xs : 'T list ) =
270- mapIndexed ( fun i x -> f x) xs
301+ let map ( mapping : 'T -> 'U ) ( xs : 'T list ) =
302+ let root = List.Empty
303+ let folder ( acc : 'U list ) x = acc.AppendConsNoTail ( mapping x)
304+ let node = fold folder root xs
305+ node.SetConsTail List.Empty
306+ root.Tail
271307
272308let indexed xs =
273309 mapIndexed ( fun i x -> ( i, x)) xs
274310
275- let map2 f xs ys =
276- Seq.map2 f xs ys |> ofSeq
311+ let map2 ( mapping : 'T1 -> 'T2 -> 'U ) ( xs : 'T1 list ) ( ys : 'T2 list ) =
312+ let root = List.Empty
313+ let folder ( acc : 'U list ) x y = acc.AppendConsNoTail ( mapping x y)
314+ let node = fold2 folder root xs ys
315+ node.SetConsTail List.Empty
316+ root.Tail
277317
278- let mapIndexed2 f xs ys =
279- Seq.mapi2 f xs ys |> ofSeq
318+ let mapIndexed2 ( mapping : int -> 'T1 -> 'T2 -> 'U ) ( xs : 'T1 list ) ( ys : 'T2 list ) =
319+ let rec loop i ( acc : 'U list ) ( xs : 'T1 list ) ( ys : 'T2 list ) =
320+ if xs.IsEmpty || ys.IsEmpty then acc
321+ else
322+ let node = acc.AppendConsNoTail ( mapping i xs.Head ys.Head)
323+ loop ( i + 1 ) node xs.Tail ys.Tail
324+ let root = List.Empty
325+ let node = loop 0 root xs ys
326+ node.SetConsTail List.Empty
327+ root.Tail
280328
281- let map3 f xs ys zs =
282- Seq.map3 f xs ys zs |> ofSeq
329+ let map3 ( mapping : 'T1 -> 'T2 -> 'T3 -> 'U ) ( xs : 'T1 list ) ( ys : 'T2 list ) ( zs : 'T3 list ) =
330+ let rec loop ( acc : 'U list ) ( xs : 'T1 list ) ( ys : 'T2 list ) ( zs : 'T3 list ) =
331+ if xs.IsEmpty || ys.IsEmpty || zs.IsEmpty then acc
332+ else
333+ let node = acc.AppendConsNoTail ( mapping xs.Head ys.Head zs.Head)
334+ loop node xs.Tail ys.Tail zs.Tail
335+ let root = List.Empty
336+ let node = loop root xs ys zs
337+ node.SetConsTail List.Empty
338+ root.Tail
283339
284- let mapFold ( f : 'S -> 'T -> 'R * 'S ) s xs =
340+ let mapFold ( mapping : 'State -> 'T -> 'Result * 'State ) ( state : 'State ) ( xs : 'T list ) =
285341 let folder ( nxs , fs ) x =
286- let nx , fs = f fs x
342+ let nx , fs = mapping fs x
287343 List.Cons( nx, nxs), fs
288- let nxs , s = fold folder ( List.Empty, s ) xs
289- reverse nxs, s
344+ let nxs , state = fold folder ( List.Empty, state ) xs
345+ reverse nxs, state
290346
291- let mapFoldBack ( f : 'T -> 'S -> 'R * 'S ) xs s =
292- mapFold ( fun s v -> f v s ) s ( reverse xs)
347+ let mapFoldBack ( mapping : 'T -> 'State -> 'Result * 'State ) ( xs : 'T list ) ( state : 'State ) =
348+ mapFold ( fun acc x -> mapping x acc ) state ( reverse xs)
293349
294- let iterate f xs =
295- fold ( fun () x -> f x) () xs
350+ let iterate action xs =
351+ fold ( fun () x -> action x) () xs
296352
297- let iterate2 f xs ys =
298- fold2 ( fun () x y -> f x y) () xs ys
353+ let iterate2 action xs ys =
354+ fold2 ( fun () x y -> action x y) () xs ys
299355
300- let iterateIndexed f xs =
301- fold ( fun i x -> f i x; i + 1 ) 0 xs |> ignore
356+ let iterateIndexed action xs =
357+ fold ( fun i x -> action i x; i + 1 ) 0 xs |> ignore
302358
303- let iterateIndexed2 f xs ys =
304- fold2 ( fun i x y -> f i x y; i + 1 ) 0 xs ys |> ignore
359+ let iterateIndexed2 action xs ys =
360+ fold2 ( fun i x y -> action i x y; i + 1 ) 0 xs ys |> ignore
305361
306362let tryPickIndexed ( f : int -> 'T -> 'U option ) ( xs : 'T list ) =
307- let rec loop i ( ys : 'T list ) =
308- if ys .IsEmpty then None
363+ let rec loop i ( xs : 'T list ) =
364+ if xs .IsEmpty then None
309365 else
310- match f i ys .Head with
366+ match f i xs .Head with
311367 | Some _ as res -> res
312- | None -> loop ( i + 1 ) ys .Tail
368+ | None -> loop ( i + 1 ) xs .Tail
313369 loop 0 xs
314370
315371let tryPickIndexedBack ( f : int -> 'T -> 'U option ) ( xs : 'T list ) =
316- let rec loop i acc ( ys : 'T list ) =
317- if ys .IsEmpty then acc
372+ let rec loop i acc ( xs : 'T list ) =
373+ if xs .IsEmpty then acc
318374 else
319375 let result =
320- match f i ys .Head with
376+ match f i xs .Head with
321377 | Some _ as res -> res
322378 | None -> acc
323- loop ( i + 1 ) result ys .Tail
379+ loop ( i + 1 ) result xs .Tail
324380 loop 0 None xs
325381
326382let tryPick f xs =
@@ -376,33 +432,43 @@ let findIndexBack f xs: int =
376432 | Some x -> x
377433
378434let tryItem n ( xs : 'T list ) =
379- let rec loop i ( ys : 'T list ) =
380- if ys .IsEmpty then None
435+ let rec loop i ( xs : 'T list ) =
436+ if xs .IsEmpty then None
381437 else
382- if i = n then Some ys .Head
383- else loop ( i + 1 ) ys .Tail
438+ if i = n then Some xs .Head
439+ else loop ( i + 1 ) xs .Tail
384440 loop 0 xs
385441
386442let item n ( xs : 'T list ) = xs.Item( n)
387443
388- let filter f xs =
389- fold ( fun acc x ->
390- if f x
391- then List.Cons( x, acc)
392- else acc) List.Empty xs
393- |> reverse
394-
395- let partition f xs =
396- fold ( fun ( lacc , racc ) x ->
397- if f x then List.Cons( x, lacc), racc
398- else lacc, List.Cons( x, racc)) ( List.Empty, List.Empty) ( reverse xs)
444+ let filter f ( xs : 'T list ) =
445+ let root = List.Empty
446+ let folder ( acc : 'T list ) x =
447+ if f x then acc.AppendConsNoTail x else acc
448+ let node = fold folder root xs
449+ node.SetConsTail List.Empty
450+ root.Tail
399451
400- let choose f xs =
401- fold ( fun acc x ->
452+ let partition f ( xs : 'T list ) =
453+ let root1 , root2 = List.Empty, List.Empty
454+ let folder ( lacc : 'T list , racc : 'T list ) x =
455+ if f x
456+ then lacc.AppendConsNoTail x, racc
457+ else lacc, racc.AppendConsNoTail x
458+ let node1 , node2 = fold folder ( root1, root2) xs
459+ node1.SetConsTail List.Empty
460+ node2.SetConsTail List.Empty
461+ root1.Tail, root2.Tail
462+
463+ let choose f ( xs : 'T list ) =
464+ let root = List.Empty
465+ let folder ( acc : 'T list ) x =
402466 match f x with
403- | Some y -> List.Cons( y, acc)
404- | None -> acc) List.Empty xs
405- |> reverse
467+ | Some y -> acc.AppendConsNoTail y
468+ | None -> acc
469+ let node = fold folder root xs
470+ node.SetConsTail List.Empty
471+ root.Tail
406472
407473let contains ( value : 'T ) ( xs : 'T list ) ( [<Inject>] eq : System.Collections.Generic.IEqualityComparer < 'T >) =
408474 tryFindIndex ( fun v -> eq.Equals ( value, v)) xs |> Option.isSome
@@ -413,11 +479,13 @@ let except (itemsToExclude: seq<'T>) (xs: 'T list) ([<Inject>] eq: System.Collec
413479 let cached = System.Collections.Generic.HashSet( itemsToExclude, eq)
414480 xs |> filter cached.Add
415481
416- let initialize n f =
417- let mutable res = List.Empty
482+ let initialize n ( f : int -> 'T ) =
483+ let root = List.Empty
484+ let mutable node = root
418485 for i = 0 to n - 1 do
419- res <- List.Cons( f i, res)
420- res |> reverse
486+ node <- node.AppendConsNoTail ( f i)
487+ node.SetConsTail List.Empty
488+ root.Tail
421489
422490let replicate n x =
423491 initialize n ( fun _ -> x)
@@ -439,7 +507,7 @@ let forAll2 f xs ys =
439507let exists f xs =
440508 tryFindIndex f xs |> Option.isSome
441509
442- let rec exists2 f ( xs : 'T list ) ( ys : 'U list ) =
510+ let rec exists2 ( f : 'T1 -> 'T2 -> bool ) ( xs : 'T1 list ) ( ys : 'T2 list ) =
443511 match xs.IsEmpty, ys.IsEmpty with
444512 | true , true -> false
445513 | false , false -> f xs.Head ys.Head || exists2 f xs.Tail ys.Tail
0 commit comments