locked
Tuple weirdness with FSharp and Silverlight 5 RRS feed

  • General discussion

  • Hi all,

    I need to use FSharp in a Silverlight 5 program. To do this, I've downloaded the official FSharp for Silverlight 5 release here: http://www.microsoft.com/en-us/download/details.aspx?id=11100

    When I use it, the compiler complains that the System.Tuple types are defined in both mscorlib.dll and FSharp.Core.dll. Sure enough, there are definitions for System.Tuple types in FSharp.Core.dll, which weren't present in previous FSharp for Silverlight releases.

    This is worrying. Why are the System.Tuple types defined in FSharp.Core.dll, given that they are already in Silverlight? And how can I use System.Tuple in a SL 5 + FSharp application, given that I absolutely need to reference both FSharp.Core.dll and mscorlib.dll?

    Monday, July 2, 2012 5:46 AM

All replies

  • I can't speculate on the duplication and I'm not expert in F#, but I'm assuming you could do one of the following:

    1 - Fully qualify your usages. PITA, but not bad if you're only using a few:
        let myTuple = new System.Tuple(x, y);
    2 - Alias/abbreviate the fully qualified type or module: http://stackoverflow.com/questions/3918744/how-to-use-namespace-or-type-alias-abbreviation
    3 - Create your own wrapper class in a local namespace that wraps the functionality of Tuple.  The implementation in that class would be simple (as Tuple is simple), and that class would just need to qualify or abbreviate the wrapped usage of tuple.  The purpose of this one is so that you can use the wrapper instead of having to constantly perform number 1 or 2.  Call it 'Pair' or something to avoid having a local class named Tuple as well.

    Monday, July 2, 2012 7:53 AM
  • That won't work. The two implementations of Tuple are both in the same namespace, even though they are in different assemblies. They're both in System. I don't know how to tell the compiler to use one or the other, because their fully qualified name is the same.

    Monday, July 2, 2012 9:58 AM
  • That's pretty funny.  You could always just write your own implementation - it's not a very complicated class.  Here's a Tuple implementation I had to write for WP7 since it doesn't exist out of the box.  You could slap this in another assembly in C# or convert it to F# to use in your app.  I'd suggest changing the name from Tuple so you don't have an another ambiguity issue.

    public abstract class Tuple
        {
            public static Tuple<T1> Create<T1>(T1 item1)
            {
                return new Tuple<T1>(item1);
            }
    
            public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2)
            {
                return new Tuple<T1, T2>(item1, item2);
            }
    
            public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3)
            {
                return new Tuple<T1, T2, T3>(item1, item2, item3);
            }
    
            public static Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4)
            {
                return new Tuple<T1, T2, T3, T4>(item1, item2, item3, item4);
            }
        }
    
        public class Tuple<T1> : Tuple
        {
            public T1 Item1 { get; set; }
    
            public Tuple(T1 item1)
            {
                Item1 = item1;
            }
        }
    
        public class Tuple<T1, T2> : Tuple<T1>
        {
            public T2 Item2 { get; set; }
    
            public Tuple(T1 item1, T2 item2) : base(item1)
            {
                Item2 = item2;
            }
        }
    
        public class Tuple<T1, T2, T3> : Tuple<T1, T2>
        {
            public T3 Item3 { get; set; }
    
            public Tuple(T1 item1, T2 item2, T3 item3) : base(item1, item2)
            {
                Item3 = item3;
            }
        }
    
        public class Tuple<T1, T2, T3, T4> : Tuple<T1, T2, T3>
        {
            public T4 Item4 { get; set; }
    
            public Tuple(T1 item1, T2 item2, T3 item3, T4 item4) : base(item1, item2, item3)
            {
                Item4 = item4;
            }
        }



    Monday, July 2, 2012 10:41 AM
  • You could change the Alias property of the reference to mscorlib.dll from "global" to "global, system".

    You can then prepend code files where a conflict occurs with "extern alias system;" and specify the mscorlib version of System.Tuple via "system::System.Tuple".

    If you need to specify the FSharp.Core version, as well, you could assign a different alias to the reference to that assembly as well.

    Saturday, July 7, 2012 3:54 AM