They are simply sugar for subtype constraints and are still usefull to avoid struct boxing on interfaces for performance reasons in addition to the uses you cited from the msdn site.

By on 7/27/2010 5:26 AM ()

I believe that flexible types are really something of a legacy feature and not very useful anymore. In older versions of the language, you couldn't apply a let bound function to an argument which was a subtype of the declared argument type unless you used a flexible type. That is, a function like Seq.append needed to be declared to have type #seq<'a> -> #seq<'a> -> seq<'a> if you wanted to be able to apply it to lists, arrays, etc. without upcasting the arguments. However, this is no longer how the language works (see section 14.4.2 of the spec), so flexible types are not typically needed any more.

Flexible types almost never make sense as return types for a function because the inheritance goes the wrong direction (e.g. a function of type unit -> #seq<int> would need to be able to return whichever subtype of seq<int> the caller wanted, be it an int[], an int list, etc.).

By on 7/25/2010 3:40 PM ()


int[], an int list, etc.).

return whichever subtype of seq<int> the caller wanted, be it an

function of type unit -> #seq<int> would need to be able to

function because the inheritance goes the wrong direction (e.g. a

Flexible types almost never make sense as return types for a


Of course I didn't mean that the return type of any concrete function is ever going to be flexible. You are right that it is nonsensical. However, what I mean is that as function return types are not automatically up-cast, there may be some arguments binding to higher-order functions whose return types may need to be annotated as flexible. The following example from MSDN is elucidating.

[link:msdn.microsoft.com]
let iterate1 (f : unit -> seq<int>) =
for e in f() do printfn "%d" e
let iterate2 (f : unit -> #seq<int>) =
for e in f() do printfn "%d" e

// Passing a function that takes a list requires a cast.
iterate1 (fun () -> [1] :> seq<int>)

// Passing a function that takes a list to the version that specifies a
// flexible type as the return value is OK as is.
iterate2 (fun () -> [1])
Note, the need for flexibility arises because the return of the argument function, i.e., f, cannot be up-cast. I can't think of any other utility for flexible types.

By on 7/25/2010 5:28 PM ()
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