11module LinkedList
22
3- open Fable.Core
4-
53module SR =
64 let indexOutOfBounds = " The index was outside the range of elements in the list."
75 let inputListWasEmpty = " List was empty"
@@ -12,11 +10,10 @@ module SR =
1210 let listsHadDifferentLengths = " The lists had different lengths."
1311 let notEnoughElements = " The input sequence has an insufficient number of elements."
1412
15- [<Struct>]
1613[<CustomEquality; CustomComparison>]
1714// [<CompiledName("FSharpList`1")>]
18- type List < 'T when 'T: comparison > =
19- { head: 'T ; mutable tail: List < 'T > option }
15+ type LinkedList < 'T when 'T: comparison > =
16+ { head: 'T ; mutable tail: LinkedList < 'T > option }
2017
2118 static member inline Empty : 'T list = { head = Unchecked.defaultof< 'T>; tail = None }
2219 static member inline Cons ( x : 'T , xs : 'T list ) = { head = x; tail = Some xs }
@@ -107,7 +104,7 @@ type List<'T when 'T: comparison> =
107104 member xs.GetEnumerator (): System.Collections.IEnumerator =
108105 (( xs :> System.Collections.Generic.IEnumerable< 'T>) .GetEnumerator() :> System.Collections.IEnumerator)
109106
110- and ListEnumerator < 'T when 'T : comparison >( xs : List < 'T > ) =
107+ and ListEnumerator < 'T when 'T : comparison >( xs : 'T list ) =
111108 let mutable it = xs
112109 let mutable current = Unchecked.defaultof< 'T>
113110 interface System.Collections.Generic.IEnumerator< 'T> with
@@ -127,7 +124,8 @@ and ListEnumerator<'T when 'T: comparison>(xs: List<'T>) =
127124 interface System.IDisposable with
128125 member __.Dispose () = ()
129126
130- and 'T list when 'T : comparison = List< 'T>
127+ and 'T list when 'T : comparison = LinkedList< 'T>
128+ and List < 'T > when 'T : comparison = LinkedList< 'T>
131129
132130// [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
133131// [<RequireQualifiedAccess>]
@@ -186,6 +184,10 @@ let toArray (xs: 'T list) =
186184 loop 0 xs
187185 res
188186
187+ // let rec fold (folder: 'State -> 'T -> 'State) (state: 'State) (xs: 'T list) =
188+ // if xs.IsEmpty then state
189+ // else fold folder (folder state xs.Head) xs.Tail
190+
189191let fold ( folder : 'State -> 'T -> 'State ) ( state : 'State ) ( xs : 'T list ) =
190192 let mutable acc = state
191193 let mutable xs = xs
@@ -207,6 +209,46 @@ let foldIndexed (folder: int -> 'State -> 'T -> 'State) (state: 'State) (xs: 'T
207209 else loop ( i + 1 ) ( folder i acc xs.Head) xs.Tail
208210 loop 0 state xs
209211
212+ // let rec fold2 (folder: 'State -> 'T1 -> 'T2 -> 'State) (state: 'State) (xs: 'T1 list) (ys: 'T2 list) =
213+ // if xs.IsEmpty || ys.IsEmpty then state
214+ // else fold2 folder (folder state xs.Head ys.Head) xs.Tail ys.Tail
215+
216+ let fold2 ( folder : 'State -> 'T1 -> 'T2 -> 'State ) ( state : 'State ) ( xs : 'T1 list ) ( ys : 'T2 list ) =
217+ let mutable acc = state
218+ let mutable xs = xs
219+ let mutable ys = ys
220+ while not xs.IsEmpty && not ys.IsEmpty do
221+ acc <- folder acc xs.Head ys.Head
222+ xs <- xs.Tail
223+ ys <- ys.Tail
224+ acc
225+
226+ let foldBack2 ( folder : 'T1 -> 'T2 -> 'State -> 'State ) ( xs : 'T1 list ) ( ys : 'T2 list ) ( state : 'State ) =
227+ // fold2 (fun acc x y -> folder x y acc) state (reverse xs) (reverse ys)
228+ Array.foldBack2 folder ( toArray xs) ( toArray ys) state
229+
230+ let unfold ( gen : 'State -> ( 'T * 'State ) option ) ( state : 'State ) =
231+ let rec loop acc ( node : 'T list ) =
232+ match gen acc with
233+ | None -> node
234+ | Some ( x, acc) -> loop acc ( node.AppendConsNoTail x)
235+ let root = List.Empty
236+ let node = loop state root
237+ node.SetConsTail List.Empty
238+ root.Tail
239+
240+ let iterate action xs =
241+ fold ( fun () x -> action x) () xs
242+
243+ let iterate2 action xs ys =
244+ fold2 ( fun () x y -> action x y) () xs ys
245+
246+ let iterateIndexed action xs =
247+ fold ( fun i x -> action i x; i + 1 ) 0 xs |> ignore
248+
249+ let iterateIndexed2 action xs ys =
250+ fold2 ( fun i x y -> action i x y; i + 1 ) 0 xs ys |> ignore
251+
210252let toSeq ( xs : 'T list ): 'T seq =
211253 xs :> System.Collections.Generic.IEnumerable< 'T>
212254
@@ -221,45 +263,27 @@ let ofArray (xs: 'T[]) =
221263
222264let ofSeq ( xs : seq < 'T >): 'T list =
223265 match xs with
224- | :? list < 'T> as lst -> lst
225- | :? array < 'T> as arr -> ofArray arr
266+ | :? array < 'T> as xs -> ofArray xs
267+ | :? list < 'T> as xs -> xs
226268 | _ ->
227269 let root = List.Empty
228- let node = Seq.fold ( fun ( acc : 'T list ) x -> acc.AppendConsNoTail x) root xs
270+ let mutable node = root
271+ for x in xs do
272+ node <- node.AppendConsNoTail x
229273 node.SetConsTail List.Empty
230274 root.Tail
231275
232276let concat ( lists : seq < 'T list >) =
233277 let root = List.Empty
234278 let mutable node = root
235- for xs in lists do
236- node <- fold ( fun acc x -> acc.AppendConsNoTail x) node xs
279+ let action xs = node <- fold ( fun acc x -> acc.AppendConsNoTail x) node xs
280+ match lists with
281+ | :? array< 'T list> as xs -> Array.iter action xs
282+ | :? list< 'T list> as xs -> iterate action xs
283+ | _ -> for xs in lists do action xs
237284 node.SetConsTail List.Empty
238285 root.Tail
239286
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-
263287let scan ( folder : 'State -> 'T -> 'State ) ( state : 'State ) ( xs : 'T list ) =
264288 let root = List.Empty
265289 let mutable node = root.AppendConsNoTail state
@@ -273,7 +297,8 @@ let scan (folder: 'State -> 'T -> 'State) (state: 'State) (xs: 'T list) =
273297 root.Tail
274298
275299let scanBack ( folder : 'T -> 'State -> 'State ) ( xs : 'T list ) ( state : 'State ) =
276- Array.scanBack folder ( toArray xs) state |> ofArray
300+ Array.scanBack folder ( toArray xs) state
301+ |> ofArray
277302
278303let append ( xs : 'T list ) ( ys : 'T list ) =
279304 fold ( fun acc x -> List.Cons( x, acc)) ys ( reverse xs)
@@ -338,27 +363,17 @@ let map3 (mapping: 'T1 -> 'T2 -> 'T3 -> 'U) (xs: 'T1 list) (ys: 'T2 list) (zs: '
338363 root.Tail
339364
340365let 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
366+ let folder ( node : 'Result list , st ) x =
367+ let r , st = mapping st x
368+ node.AppendConsNoTail r, st
369+ let root = List.Empty
370+ let node , state = fold folder ( root, state) xs
371+ node.SetConsTail List.Empty
372+ root.Tail, state
346373
347374let mapFoldBack ( mapping : 'T -> 'State -> 'Result * 'State ) ( xs : 'T list ) ( state : 'State ) =
348375 mapFold ( fun acc x -> mapping x acc) state ( reverse xs)
349376
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-
362377let tryPickIndexed ( f : int -> 'T -> 'U option ) ( xs : 'T list ) =
363378 let rec loop i ( xs : 'T list ) =
364379 if xs.IsEmpty then None
@@ -525,21 +540,21 @@ let zip xs ys =
525540let zip3 xs ys zs =
526541 map3 ( fun x y z -> x, y, z) xs ys zs
527542
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
543+ let sortWith ( comparer : 'T -> 'T -> int ) ( xs : 'T list ) =
544+ let arr = toArray xs
545+ Array.sortInPlaceWith comparer arr
546+ arr |> ofArray
532547
533- let sort ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'T >): 'T list =
548+ let sort ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'T >) =
534549 sortWith ( fun x y -> comparer.Compare( x, y)) xs
535550
536- let sortBy ( projection : 'T -> 'U ) ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'U >): 'T list =
551+ let sortBy ( projection : 'T -> 'U ) ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'U >) =
537552 sortWith ( fun x y -> comparer.Compare( projection x, projection y)) xs
538553
539- let sortDescending ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'T >): 'T list =
554+ let sortDescending ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'T >) =
540555 sortWith ( fun x y -> comparer.Compare( x, y) * - 1 ) xs
541556
542- let sortByDescending ( projection : 'T -> 'U ) ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'U >): 'T list =
557+ let sortByDescending ( projection : 'T -> 'U ) ( xs : 'T list ) ( [<Inject>] comparer : System.Collections.Generic.IComparer < 'U >) =
543558 sortWith ( fun x y -> comparer.Compare( projection x, projection y) * - 1 ) xs
544559
545560let sum ( xs : 'T list ) ( [<Inject>] adder : IGenericAdder < 'T >): 'T =
@@ -569,30 +584,56 @@ let averageBy (f: 'T -> 'T2) (xs: 'T list) ([<Inject>] averager: IGenericAverage
569584 averager.DivideByInt( total, length xs)
570585
571586let permute f ( xs : 'T list ) =
572- Array.ofSeq xs
587+ toArray xs
573588 |> Array.permute f
574589 |> ofArray
575590
576591let chunkBySize ( chunkSize : int ) ( xs : 'T list ): 'T list list =
577- Array.ofSeq xs
592+ toArray xs
578593 |> Array.chunkBySize chunkSize
594+ |> Array.map ofArray
579595 |> ofArray
580- |> map ofArray
581596
582- let skip i ( xs : 'T list ) =
583- Seq.skip i xs |> ofSeq
597+ let rec skip count ( xs : 'T list ) =
598+ if count <= 0 then xs
599+ elif xs.IsEmpty then invalidArg " list" SR.notEnoughElements
600+ else skip ( count - 1 ) xs.Tail
584601
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
602+ let rec skipWhile predicate ( xs : 'T list ) =
603+ if xs.IsEmpty then xs
604+ elif not ( predicate xs.Head) then xs
605+ else skipWhile predicate xs.Tail
606+
607+ let take count ( xs : 'T list ) =
608+ if count < 0 then invalidArg " count" SR.inputMustBeNonNegative
609+ let rec loop i ( acc : 'T list ) ( xs : 'T list ) =
610+ if i <= 0 then acc
611+ elif xs.IsEmpty then invalidArg " list" SR.notEnoughElements
612+ else loop ( i - 1 ) ( acc.AppendConsNoTail xs.Head) xs.Tail
613+ let root = List.Empty
614+ let node = loop count root xs
615+ node.SetConsTail List.Empty
616+ root.Tail
590617
591618let takeWhile predicate ( xs : 'T list ) =
592- Seq.takeWhile predicate xs |> ofSeq
619+ let rec loop ( acc : 'T list ) ( xs : 'T list ) =
620+ if xs.IsEmpty then acc
621+ elif not ( predicate xs.Head) then acc
622+ else loop ( acc.AppendConsNoTail xs.Head) xs.Tail
623+ let root = List.Empty
624+ let node = loop root xs
625+ node.SetConsTail List.Empty
626+ root.Tail
593627
594- let truncate i xs =
595- Seq.truncate i xs |> ofSeq
628+ let truncate count ( xs : 'T list ) =
629+ let rec loop i ( acc : 'T list ) ( xs : 'T list ) =
630+ if i <= 0 then acc
631+ elif xs.IsEmpty then acc
632+ else loop ( i - 1 ) ( acc.AppendConsNoTail xs.Head) xs.Tail
633+ let root = List.Empty
634+ let node = loop count root xs
635+ node.SetConsTail List.Empty
636+ root.Tail
596637
597638let getSlice ( startIndex : int option ) ( endIndex : int option ) ( xs : 'T list ) =
598639 let len = length xs
@@ -656,24 +697,28 @@ let where predicate (xs: 'T list) =
656697 filter predicate xs
657698
658699let pairwise ( xs : 'T list ) =
659- Seq.pairwise xs |> ofSeq
700+ toArray xs
701+ |> Array.pairwise
702+ |> ofArray
660703
661704let windowed ( windowSize : int ) ( xs : 'T list ): 'T list list =
662- Seq.windowed windowSize xs
663- |> ofSeq
664- |> map ofArray
705+ toArray xs
706+ |> Array.windowed windowSize
707+ |> Array.map ofArray
708+ |> ofArray
665709
666710let splitInto ( chunks : int ) ( xs : 'T list ): 'T list list =
667- Array.ofSeq xs
711+ toArray xs
668712 |> Array.splitInto chunks
713+ |> Array.map ofArray
669714 |> ofArray
670- |> map ofArray
671715
672716let transpose ( lists : seq < 'T list >): 'T list list =
673717 lists
674- |> Seq.transpose
675- |> Seq.map ofSeq
676- |> ofSeq
718+ |> Seq.map toArray
719+ |> Array.transpose
720+ |> Array.map ofArray
721+ |> ofArray
677722
678723// let rev = reverse
679724// let init = initialize
0 commit comments