immutable な配列クラス作ってみた #fsharp
需要あるのか分からないけど、カッとなって作った。昨晩作り始めて、先ほど出張帰りの新幹線で完成。テストはしていないッ(キリッ
名前は迷ったんだけど、あまり長い名前にしたくなかったので Immutarray というちょっと変な名前(勝手な造語)にした。ImmutableArray だと immutable collections と被るみたいだし。心のなかでは「イミュータレイ」って読んでる。
コピペしてご自由にお使いください。名前等、気に食わなければ好きなように変更してどうぞ。
※ よく分からず inline 付けまくってみたけどいいんかいな?
namespace (好きな名前を入れてね) open System type private ImmutarrayData<'a> = { RawArray : 'a[] } type Immutarray<'a when 'a : equality> (rawArray : 'a[]) = let data = { RawArray = rawArray } member inline private this.Data = data member this.Length = data.RawArray.Length member this.Item with get i = data.RawArray.[i] member this.__RAW_ARRAY__ = data.RawArray member this.ToArray() = Array.copy data.RawArray member this.Equals (x : Immutarray<'a>) = (data :> IEquatable<_>).Equals x.Data override this.Equals x = match x with :? Immutarray<'a> as x -> this.Equals x | _ -> false override this.GetHashCode () = data.GetHashCode() interface IEquatable<Immutarray<'a>> with member this.Equals x = this.Equals x interface seq<'a> with member this.GetEnumerator() = (data.RawArray :> 'a seq).GetEnumerator() interface Collections.IEnumerable with member this.GetEnumerator() = data.RawArray.GetEnumerator() [<Sealed; AbstractClass; Runtime.CompilerServices.Extension>] type Immutarray = static member inline private Raw (array : Immutarray<_>) = array.__RAW_ARRAY__ static member ForEach (array, action) = Array.ForEach (Immutarray.Raw array, action) static member ConvertAll (array, converter) = Immutarray (Array.ConvertAll (Immutarray.Raw array, converter)) static member Exists (array, predicate) = Array.Exists (Immutarray.Raw array, predicate) static member TrueForAll (array, predicate) = Array.TrueForAll (Immutarray.Raw array, predicate) static member Find (array, predicate) = Array.Find (Immutarray.Raw array, predicate) static member FindIndex (array, predicate) = Array.FindIndex (Immutarray.Raw array, predicate) static member FindLast (array, predicate) = Array.FindLast (Immutarray.Raw array, predicate) static member FindLastIndex (array, predicate) = Array.FindLastIndex (Immutarray.Raw array, predicate) static member FindAll (array, predicate) = Immutarray(Array.FindAll (Immutarray.Raw array, predicate)) static member IndexOf (array, value) = Array.IndexOf (Immutarray.Raw array, value) static member LastIndexOf (array, value) = Array.LastIndexOf (Immutarray.Raw array, value) static member BinarySearch (array, value) = Array.BinarySearch (Immutarray.Raw array, value) static member BinarySearch (array, value, comparer) = Array.BinarySearch (Immutarray.Raw array, value, comparer) static member BinarySearch (array, index, length, value) = Array.BinarySearch (Immutarray.Raw array, index, length, value) static member BinarySearch (array, index, length, value, comparer) = Array.BinarySearch (Immutarray.Raw array, index, length, value, comparer) [<Runtime.CompilerServices.Extension>] static member ToImmutarray source = Immutarray (Seq.toArray source) [<CompilationRepresentation( CompilationRepresentationFlags.ModuleSuffix ); RequireQualifiedAccess>] module Immutarray = let inline private raw (a : Immutarray<'a>) = a.__RAW_ARRAY__ let inline ofArray array = Immutarray array let inline ofList list = Array.ofList list |> ofArray let inline ofSeq source = Array.ofSeq source |> ofArray let inline toArray array = Array.copy (raw array) let inline toList array = Array.toList (raw array) let inline toSeq array = Array.toSeq (raw array) let inline length array = raw array |> Array.length let inline get (array : Immutarray<'a>) index = array.[index] let inline empty<'a when 'a : equality> = Immutarray<'a> [||] let inline init count initializer = Array.init count initializer |> ofArray let inline create count value = Array.create count value |> ofArray let inline zeroCreate count = Array.zeroCreate count |> ofArray let inline map mapping array = Array.map mapping (raw array) |> ofArray let inline mapi mapping array = Array.mapi mapping (raw array) |> ofArray let inline map2 mapping array1 array2 = Array.map2 mapping (raw array1) (raw array2) |> ofArray let inline mapi2 mapping array1 array2 = Array.mapi2 mapping (raw array1) (raw array2) |> ofArray let inline collect mapping array = Array.collect mapping (raw array) |> ofArray let inline filter predicate array = raw array |> Array.filter predicate |> ofArray let inline choose chooser array = raw array |> Array.choose chooser |> ofArray let inline rev array = raw array |> Array.rev |> ofArray let inline sort array = raw array |> Array.sort |> ofArray let inline sortBy projection array = raw array |> Array.sortBy projection |> ofArray let inline sortWith comparer array = raw array |> Array.sortWith comparer |> ofArray let inline permutate indexMap array = raw array |> Array.permute indexMap |> ofArray let inline sub array startIndex count = Array.sub (raw array) startIndex count |> ofArray let inline iter action array = Array.iter action (raw array) let inline iteri action array = Array.iteri action (raw array) let inline iter2 action array1 array2 = Array.iter2 action (raw array1) (raw array2) let inline iteri2 action array1 array2 = Array.iteri2 action (raw array1) (raw array2) let inline isEmpty array = Array.isEmpty (raw array) let inline forall predicate array = Array.forall predicate (raw array) let inline exists predicate array = Array.exists predicate (raw array) let inline forall2 predicate array1 array2 = Array.forall2 predicate (raw array1) (raw array2) let inline exists2 predicate array1 array2 = Array.exists2 predicate (raw array1) (raw array2) let inline max array = Array.max (raw array) let inline min array = Array.min (raw array) let inline sum array = Array.sum (raw array) let inline average array = Array.average (raw array) let inline maxBy projection array = Array.maxBy projection (raw array) let inline minBy projection array = Array.minBy projection (raw array) let inline sumBy projection array = Array.sumBy projection (raw array) let inline averageBy projection array = Array.averageBy projection (raw array) let inline fold folder state array = Array.fold folder state (raw array) let inline foldBack folder array state = Array.foldBack folder (raw array) state let inline fold2 folder state array1 array2 = Array.fold2 folder state (raw array1) (raw array2) let inline foldBack2 folder array1 array2 state = Array.foldBack2 folder (raw array1) (raw array2) state let inline reduce reduction array = Array.reduce reduction (raw array) let inline reduceBack reduction array = Array.reduceBack reduction (raw array) let inline scan folder state array = Array.scan folder state (raw array) |> ofArray let inline scanBack folder array state = Array.scanBack folder (raw array) state |> ofArray let inline find predicate array = Array.find predicate (raw array) let inline findIndex predicate array = Array.findIndex predicate (raw array) let inline tryFind predicate array = Array.tryFind predicate (raw array) let inline tryFindIndex predicate array = Array.tryFindIndex predicate (raw array) let inline pick chooser array = Array.pick chooser (raw array) let inline tryPick chooser array = Array.tryPick chooser (raw array) let inline append array1 array2 = Array.append (raw array1) (raw array2) |> ofArray let inline concat arrays = arrays |> Seq.map raw |> Array.concat |> ofArray let inline partition predicate array = let a1, a2 = Array.partition predicate (raw array) in Immutarray a1, Immutarray a2 let inline zip array1 array2 = Array.zip (raw array1) (raw array2) |> ofArray let inline zip3 array1 array2 array3 = Array.zip3 (raw array1) (raw array2) (raw array3) |> ofArray let inline unzip array = let a1, a2 = Array.unzip (raw array) in Immutarray a1, Immutarray a2 let inline unzip3 array = let a1, a2, a3 = Array.unzip3 (raw array) in Immutarray a1, Immutarray a2, Immutarray a3 [<CompilationRepresentation( CompilationRepresentationFlags.ModuleSuffix ); RequireQualifiedAccess>] module Array = let toImmutarray = Immutarray.ofArray let ofImmutarray = Immutarray.toArray [<CompilationRepresentation( CompilationRepresentationFlags.ModuleSuffix ); RequireQualifiedAccess>] module List = let toImmutarray = Immutarray.ofList let ofImmutarray = Immutarray.toList [<CompilationRepresentation( CompilationRepresentationFlags.ModuleSuffix ); RequireQualifiedAccess>] module Seq = let toImmutarray = Immutarray.ofSeq let ofImmutarray = Immutarray.toSeq [<CompilationRepresentation( CompilationRepresentationFlags.ModuleSuffix ); RequireQualifiedAccess>] module Set = let ofImmutarray (array : Immutarray<_>) = Set.ofArray array.__RAW_ARRAY__ let toImmutarray set = Immutarray (Set.toArray set) [<CompilationRepresentation( CompilationRepresentationFlags.ModuleSuffix ); RequireQualifiedAccess>] module Map = let ofImmutarray (array : Immutarray<_>) = Map.ofArray array.__RAW_ARRAY__ let toImmutarray map = Immutarray (Map.toArray map)