@@ -12,7 +12,6 @@ module SR =
1212 let listsHadDifferentLengths = " The lists had different lengths."
1313 let notEnoughElements = " The input sequence has an insufficient number of elements."
1414
15- [<Struct>]
1615[<CustomEquality; CustomComparison>]
1716// [<CompiledName("FSharpList`1")>]
1817type List < 'T when 'T: comparison > =
@@ -186,6 +185,10 @@ let toArray (xs: 'T list) =
186185 loop 0 xs
187186 res
188187
188+ // let rec fold (folder: 'State -> 'T -> 'State) (state: 'State) (xs: 'T list) =
189+ // if xs.IsEmpty then state
190+ // else fold folder (folder state xs.Head) xs.Tail
191+
189192let fold ( folder : 'State -> 'T -> 'State ) ( state : 'State ) ( xs : 'T list ) =
190193 let mutable acc = state
191194 let mutable xs = xs
@@ -207,6 +210,46 @@ let foldIndexed (folder: int -> 'State -> 'T -> 'State) (state: 'State) (xs: 'T
207210 else loop ( i + 1 ) ( folder i acc xs.Head) xs.Tail
208211 loop 0 state xs
209212
213+ // let rec fold2 (folder: 'State -> 'T1 -> 'T2 -> 'State) (state: 'State) (xs: 'T1 list) (ys: 'T2 list) =
214+ // if xs.IsEmpty || ys.IsEmpty then state
215+ // else fold2 folder (folder state xs.Head ys.Head) xs.Tail ys.Tail
216+
217+ let fold2 ( folder : 'State -> 'T1 -> 'T2 -> 'State ) ( state : 'State ) ( xs : 'T1 list ) ( ys : 'T2 list ) =
218+ let mutable acc = state
219+ let mutable xs = xs
220+ let mutable ys = ys
221+ while not xs.IsEmpty && not ys.IsEmpty do
222+ acc <- folder acc xs.Head ys.Head
223+ xs <- xs.Tail
224+ ys <- ys.Tail
225+ acc
226+
227+ let foldBack2 ( folder : 'T1 -> 'T2 -> 'State -> 'State ) ( xs : 'T1 list ) ( ys : 'T2 list ) ( state : 'State ) =
228+ // fold2 (fun acc x y -> folder x y acc) state (reverse xs) (reverse ys)
229+ Array.foldBack2 folder ( toArray xs) ( toArray ys) state
230+
231+ let unfold ( gen : 'State -> ( 'T * 'State ) option ) ( state : 'State ) =
232+ let rec loop acc ( node : 'T list ) =
233+ match gen acc with
234+ | None -> node
235+ | Some ( x, acc) -> loop acc ( node.AppendConsNoTail x)
236+ let root = List.Empty
237+ let node = loop state root
238+ node.SetConsTail List.Empty
239+ root.Tail
240+
241+ let iterate action xs =
242+ fold ( fun () x -> action x) () xs
243+
244+ let iterate2 action xs ys =
245+ fold2 ( fun () x y -> action x y) () xs ys
246+
247+ let iterateIndexed action xs =
248+ fold ( fun i x -> action i x; i + 1 ) 0 xs |> ignore
249+
250+ let iterateIndexed2 action xs ys =
251+ fold2 ( fun i x y -> action i x y; i + 1 ) 0 xs ys |> ignore
252+
210253let toSeq ( xs : 'T list ): 'T seq =
211254 xs :> System.Collections.Generic.IEnumerable< 'T>
212255
@@ -221,45 +264,27 @@ let ofArray (xs: 'T[]) =
221264
222265let ofSeq ( xs : seq < 'T >): 'T list =
223266 match xs with
224- | :? list < 'T> as lst -> lst
225- | :? array < 'T> as arr -> ofArray arr
267+ | :? array < 'T> as xs -> ofArray xs
268+ | :? list < 'T> as xs -> xs
226269 | _ ->
227270 let root = List.Empty
228- let node = Seq.fold ( fun ( acc : 'T list ) x -> acc.AppendConsNoTail x) root xs
271+ let mutable node = root
272+ for x in xs do
273+ node <- node.AppendConsNoTail x
229274 node.SetConsTail List.Empty
230275 root.Tail
231276
232277let concat ( lists : seq < 'T list >) =
233278 let root = List.Empty
234279 let mutable node = root
235- for xs in lists do
236- node <- fold ( fun acc x -> acc.AppendConsNoTail x) node xs
280+ let action xs = node <- fold ( fun acc x -> acc.AppendConsNoTail x) node xs
281+ match lists with
282+ | :? array< 'T list> as xs -> Array.iter action xs
283+ | :? list< 'T list> as xs -> iterate action xs
284+ | _ -> for xs in lists do action xs
237285 node.SetConsTail List.Empty
238286 root.Tail
239287
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
249-
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
253-
254- let unfold ( gen : 'State -> ( 'T * 'State ) option ) ( state : 'State ) =
255- let rec loop st ( node : 'T list ) =
256- match gen st with
257- | None -> node.SetConsTail List.Empty
258- | Some ( x, st) -> loop st ( node.AppendConsNoTail x)
259- let root = List.Empty
260- loop state root
261- root.Tail
262-
263288let scan ( folder : 'State -> 'T -> 'State ) ( state : 'State ) ( xs : 'T list ) =
264289 let root = List.Empty
265290 let mutable node = root.AppendConsNoTail state
@@ -273,7 +298,8 @@ let scan (folder: 'State -> 'T -> 'State) (state: 'State) (xs: 'T list) =
273298 root.Tail
274299
275300let scanBack ( folder : 'T -> 'State -> 'State ) ( xs : 'T list ) ( state : 'State ) =
276- Array.scanBack folder ( toArray xs) state |> ofArray
301+ Array.scanBack folder ( toArray xs) state
302+ |> ofArray
277303
278304let append ( xs : 'T list ) ( ys : 'T list ) =
279305 fold ( fun acc x -> List.Cons( x, acc)) ys ( reverse xs)
@@ -338,27 +364,17 @@ let map3 (mapping: 'T1 -> 'T2 -> 'T3 -> 'U) (xs: 'T1 list) (ys: 'T2 list) (zs: '
338364 root.Tail
339365
340366let mapFold ( mapping : 'State -> 'T -> 'Result * 'State ) ( state : 'State ) ( xs : 'T list ) =
341- let folder ( nxs , fs ) x =
342- let nx , fs = mapping fs x
343- List.Cons( nx, nxs), fs
344- let nxs , state = fold folder ( List.Empty, state) xs
345- reverse nxs, state
367+ let folder ( node : 'Result list , st ) x =
368+ let r , st = mapping st x
369+ node.AppendConsNoTail r, st
370+ let root = List.Empty
371+ let node , state = fold folder ( root, state) xs
372+ node.SetConsTail List.Empty
373+ root.Tail, state
346374
347375let mapFoldBack ( mapping : 'T -> 'State -> 'Result * 'State ) ( xs : 'T list ) ( state : 'State ) =
348376 mapFold ( fun acc x -> mapping x acc) state ( reverse xs)
349377
350- let iterate action xs =
351- fold ( fun () x -> action x) () xs
352-
353- let iterate2 action xs ys =
354- fold2 ( fun () x y -> action x y) () xs ys
355-
356- let iterateIndexed action xs =
357- fold ( fun i x -> action i x; i + 1 ) 0 xs |> ignore
358-
359- let iterateIndexed2 action xs ys =
360- fold2 ( fun i x y -> action i x y; i + 1 ) 0 xs ys |> ignore
361-
362378let tryPickIndexed ( f : int -> 'T -> 'U option ) ( xs : 'T list ) =
363379 let rec loop i ( xs : 'T list ) =
364380 if xs.IsEmpty then None
@@ -525,21 +541,21 @@ let zip xs ys =
525541let zip3 xs ys zs =
526542 map3 ( fun x y z -> x, y, z) xs ys zs
527543
528- let sortWith ( comparison : 'T -> 'T -> int ) ( xs : 'T list ): 'T list =
529- let values = ResizeArray ( xs )
530- values.Sort ( System.Comparison <_>( comparison ))
531- values |> ofSeq
544+ let sortWith ( comparer : 'T -> 'T -> int ) ( xs : 'T list ) =
545+ let arr = toArray xs
546+ Array.sortInPlaceWith comparer arr
547+ arr |> ofArray
532548
533- let sort ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'T >): 'T list =
549+ let sort ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'T >) =
534550 sortWith ( fun x y -> comparer.Compare( x, y)) xs
535551
536- let sortBy ( projection : 'T -> 'U ) ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'U >): 'T list =
552+ let sortBy ( projection : 'T -> 'U ) ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'U >) =
537553 sortWith ( fun x y -> comparer.Compare( projection x, projection y)) xs
538554
539- let sortDescending ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'T >): 'T list =
555+ let sortDescending ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'T >) =
540556 sortWith ( fun x y -> comparer.Compare( x, y) * - 1 ) xs
541557
542- let sortByDescending ( projection : 'T -> 'U ) ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'U >): 'T list =
558+ let sortByDescending ( projection : 'T -> 'U ) ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'U >) =
543559 sortWith ( fun x y -> comparer.Compare( projection x, projection y) * - 1 ) xs
544560
545561let sum ( xs : 'T list ) ( [<Inject>] adder : IGenericAdder < 'T >): 'T =
@@ -569,30 +585,56 @@ let averageBy (f: 'T -> 'T2) (xs: 'T list) ([<Inject>] averager: IGenericAverage
569585 averager.DivideByInt( total, length xs)
570586
571587let permute f ( xs : 'T list ) =
572- Array.ofSeq xs
588+ toArray xs
573589 |> Array.permute f
574590 |> ofArray
575591
576592let chunkBySize ( chunkSize : int ) ( xs : 'T list ): 'T list list =
577- Array.ofSeq xs
593+ toArray xs
578594 |> Array.chunkBySize chunkSize
595+ |> Array.map ofArray
579596 |> ofArray
580- |> map ofArray
581597
582- let skip i ( xs : 'T list ) =
583- Seq.skip i xs |> ofSeq
598+ let rec skip count ( xs : 'T list ) =
599+ if count <= 0 then xs
600+ elif xs.IsEmpty then invalidArg " list" SR.notEnoughElements
601+ else skip ( count - 1 ) xs.Tail
584602
585- let skipWhile predicate ( xs : 'T list ) =
586- Seq.skipWhile predicate xs |> ofSeq
587-
588- let take i xs =
589- Seq.take i xs |> ofSeq
603+ let rec skipWhile predicate ( xs : 'T list ) =
604+ if xs.IsEmpty then xs
605+ elif not ( predicate xs.Head) then xs
606+ else skipWhile predicate xs.Tail
607+
608+ let take count ( xs : 'T list ) =
609+ if count < 0 then invalidArg " count" SR.inputMustBeNonNegative
610+ let rec loop i ( acc : 'T list ) ( xs : 'T list ) =
611+ if i <= 0 then acc
612+ elif xs.IsEmpty then invalidArg " list" SR.notEnoughElements
613+ else loop ( i - 1 ) ( acc.AppendConsNoTail xs.Head) xs.Tail
614+ let root = List.Empty
615+ let node = loop count root xs
616+ node.SetConsTail List.Empty
617+ root.Tail
590618
591619let takeWhile predicate ( xs : 'T list ) =
592- Seq.takeWhile predicate xs |> ofSeq
620+ let rec loop ( acc : 'T list ) ( xs : 'T list ) =
621+ if xs.IsEmpty then acc
622+ elif not ( predicate xs.Head) then acc
623+ else loop ( acc.AppendConsNoTail xs.Head) xs.Tail
624+ let root = List.Empty
625+ let node = loop root xs
626+ node.SetConsTail List.Empty
627+ root.Tail
593628
594- let truncate i xs =
595- Seq.truncate i xs |> ofSeq
629+ let truncate count ( xs : 'T list ) =
630+ let rec loop i ( acc : 'T list ) ( xs : 'T list ) =
631+ if i <= 0 then acc
632+ elif xs.IsEmpty then acc
633+ else loop ( i - 1 ) ( acc.AppendConsNoTail xs.Head) xs.Tail
634+ let root = List.Empty
635+ let node = loop count root xs
636+ node.SetConsTail List.Empty
637+ root.Tail
596638
597639let getSlice ( startIndex : int option ) ( endIndex : int option ) ( xs : 'T list ) =
598640 let len = length xs
@@ -656,24 +698,28 @@ let where predicate (xs: 'T list) =
656698 filter predicate xs
657699
658700let pairwise ( xs : 'T list ) =
659- Seq.pairwise xs |> ofSeq
701+ toArray xs
702+ |> Array.pairwise
703+ |> ofArray
660704
661705let windowed ( windowSize : int ) ( xs : 'T list ): 'T list list =
662- Seq.windowed windowSize xs
663- |> ofSeq
664- |> map ofArray
706+ toArray xs
707+ |> Array.windowed windowSize
708+ |> Array.map ofArray
709+ |> ofArray
665710
666711let splitInto ( chunks : int ) ( xs : 'T list ): 'T list list =
667- Array.ofSeq xs
712+ toArray xs
668713 |> Array.splitInto chunks
714+ |> Array.map ofArray
669715 |> ofArray
670- |> map ofArray
671716
672717let transpose ( lists : seq < 'T list >): 'T list list =
673718 lists
674- |> Seq.transpose
675- |> Seq.map ofSeq
676- |> ofSeq
719+ |> Seq.map toArray
720+ |> Array.transpose
721+ |> Array.map ofArray
722+ |> ofArray
677723
678724// let rev = reverse
679725// let init = initialize
0 commit comments