Predicting the name of an F# type


One of the first questions I came up with yesterday when digging into F# was this: what does an F# type look like to C#? As a noob, that’s an interesting question to me. Of course, being a noob, I had no clue about how to create a custom type. So, I asked Google what an F# type definition looked like, then massaged that until I had something that I might not completely understand, but that does show the problem at hand. I created a lame Name class that only supports a first name. Boo-yah!

First, I went to an existing file in an F# library called stuff.fs. There, I added the following class:

 

     type Name(fname : string) =

         let mutable fName  = fname

         member this.FName with get() = fName

                                         and set(x) = fName <- x

For you C# heads out there, let’s look at what the code above really is saying.

  • Create a new type, Name.
  • Name has a single constructor that takes a string.
  • Name has a member variable, fName, whose value can change at runtime.
  • Name has a public property, FName, that has a getter and a setter.

OK, so now what does this look like in C#? I add the F# library to a C# project, instantiate a copy of Stuff.Name (I’ll get to the Stuff item in a moment), and then I right click on Stuff.Name and pick Go to Definition. Since we are in C# land, VS 2008 will pull up the C# vision. This looks exactly like the following:

 

using System;

 

public static class Stuff

{

 

    [Serializable]

    public class Name

    {

        public Name(string fname);

 

        public string FName { get; set; }

    }

}

That’s kind of weird. I didn’t expect to see Name declared as a inner class from a static class whose name comes from the name of the F# file. Still, that’s what we have. Does this mean that F# code doesn’t allow one to create CLR namespaces? No– of course not! So, how do you get the Name class into a CLR namespace called SomeNamespace? I did a little digging and found out how:

namespace SomeNamespace

    type Name(fname : string) =

        let mutable fName  = fname

        member this.FName with get() = fName

                                        and set(x) = fName <- x

Yeah– there’s a keyword called namespace that allows you to add objects to a CLR namespace. The odd bit here is that one doesn’t say namespace blah =. Instead, you omit the ‘=’. The ‘=’ will work, but you will get a message saying that the syntax has been deprecated. With this small change in place, things look more correct to my C# eyes. The static class disappears, and that’s good!

 

using System;

 

namespace SomeNamespace

{

    [Serializable]

    public class Name

    {

        public Name(string fname);

 

        public string FName { get; set; }

    }

}

Right now, I think my focus will be on writing F# code that plays well/looks natural to C# developers. I’ll keep that point of view until I see a reason to change.

%d bloggers like this: