Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending F# List Module

I've been adding a few handy methods to some of the F# modules such as List.

type Microsoft.FSharp.Collections.FSharpList<'a> with          //'
    static member iterWhile (f:'a -> bool) (ls:'a list) = 
        let rec iterLoop f ls = 
            match ls with
            | head :: tail -> if f head then iterLoop f tail
            | _ -> ()
        iterLoop f ls

and i'm wondering if it's possible to add mutation? I know List is immutable so how about adding a mutable method to Ref of type List. Something like this.

type Ref<'a when 'a :> Microsoft.FSharp.Collections.FSharpList<'a> > with //'
    member this.AppendMutate element =
        this := element :: !this

or is there some way to constrain a generic to only accept a mutable?

like image 910
gradbot Avatar asked Oct 01 '09 18:10

gradbot


2 Answers

Generic extension methods are now available in F# 3.1:

open System.Runtime.CompilerServices

[<Extension>]
type Utils () =
    [<Extension>]
    static member inline AppendMutate(ref: Ref<List<'a>>, elt) = ref := elt :: !ref

let ls = ref [1..10]

ls.AppendMutate(11)

printfn "%A" ls
like image 133
dharmatech Avatar answered Sep 18 '22 10:09

dharmatech


Unfortunately, it doesn't appear to be possible to add extension members to closed constructed types (e.g. Ref<int> or Seq<string>). This also applies to the code you're trying to use, since you're substituting the more specific type 'a list for the generic parameter 'T of the open generic Ref<'T> type.

like image 33
kvb Avatar answered Sep 20 '22 10:09

kvb