At least in the current version of F# I don't think you can do what you want to here. Unfortunately, it seems that the set of type constraints you use when defining extension methods need to be the same as the constraints that were used when the type was originally declared (e.g. in the case of 'a seq, that means no constraints on 'a). I'd love to be corrected if this isn't the case, because it would certainly be extremely useful to be able to add such extensions.

On the bright side, you can extend modules with additional members including whatever constraints you'd like, so the following code might be an okay compromise for you:

1
2
module Seq =
  let inline StatisticalAverage n x = x |> Seq.take n |> Seq.average
By on 4/7/2009 7:40 AM ()

This seems like an oversight in the compiler as it looks like the type-checker is discarding all constraints but not issuing any warnings.

Examples of this:

1
2
3
4
5
6
type System.Collections.Generic.IEnumerable<'a>
    when 'a : (static member ( + ) : 'a * 'a -> 'a) 
    and  'a : (static member get_Zero : unit -> 'a) with
    member x.This () = x 

let hello = "hello".This() // type constraints completely ignored
1
2
3
type System.Collections.Generic.IEnumerable<'a>
    when ^a : (static member ( + ) : ^a * 'a -> 'a) with
    member x.WhatTheFDoesThisTypeConstraintMean() = ()

When you try to use a function that require this type constraint an error is thrown.

1
2
3
4
5
6
7
8
9
10
type System.Collections.Generic.IEnumerable<'a>
    when 'a : (static member ( + ) : 'a * 'a -> 'a) 
    and  'a : (static member get_Zero : unit -> 'a) with
    member x.Sum () = x |> Seq.sum

// Error: This code is not sufficiently generic. 
// The type variable  ^a when  ^a : (static member ( + ) :  ^a *  ^a ->  ^a) 
// and  ^a : (static member get_Zero : ->  ^a) could not be generalized 
// because it would escape its scope.
  

This would be useful if implemented - but the whole area of inlines, type constraints and type extensions seems a work-in-progress at the moment. This could be where the language is finally bumping it's head against the .NET platform ceiling - unfortunately the CLR isn't designed for structural typing in languages.

This is perhaps why we won't see type classes, or higher-kinded polymorphism in the near future. According to a recent interview with Don Syme, he suggests that his role in the development in .NET generics has come to an end, leaving 'overcoming technical limitations' to 'other generations of architects'.

Roll on 2020.

regards,

Danny

By on 4/7/2009 8:45 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper