Coming from Haskell, I’d like to know if there is a way to avoid having to write the full List.map every time I want to use a map.
Is there anything such as Java’s static imports, so that I can only write map?
To recap:
I currently have to write:
List.map (fun -> 3*x) [1..10]
yet, I’d like to be able to write
map (fun -> 3*x) [1..10]
Thanks
In Java, given a class
mypackage.MyClassyou can “statically import” all static members within that class using the declarationimport static mypackage.MyClass.*. In F#, given the moduleMyNamespace.MyModuleyou can similarly make all functions within that module available without qualification using the declarationopen MyNamespace.MyModule. But as Daniel pointed out, certain module are marked with theRequireQualifiedAccessattribute which forbids this.However, you can still alias specific functions within a module similar to how you can statically import specific static members of a class in Java. For example, in Java, you can do something like
static import mypackage.MyClass.myMethodand in F# you can dolet map = List.map.Except, there is a good reason collection modules like
List,Seq, andArrayall require qualified access: they all have a similar set of functions which only act on their types and F# uses this information for its type inference. I’m not sure of the details but Haskell has some feature in its type system which allowsmap, for example, to be used on several different types without breaking type inference. Note thatSeqis a bit special though in F# (and .NET), since it works on all types implementing the interfaceIEnumerable<'a>including lists and arrays. So you could aliaslet map = Seq.mapand be able to work withmapon all those collection types but you would lose features of those concrete implementations sinceIEnumerable<'a>is the lowest common denominator among them.So in the end, in F#, the best thing to do is just use the fully qualified
mapfunctions in each collection module. It’s a small price to pay for the type inference you get in return (I sometimes wonder if I save in typing through type inference what I lose having to qualify all those collection functions, but I believe you win in the end through type inference savings especially when considering complex generic signatures and perhaps more importantly having to reason through all those type calculations).One more option for saving key strokes is through module aliases. You can do something like
module L = List. I wouldn’t do this for short, common module names likeList, but I might do it forResizeArrayor perhaps my own sometimes long-winded module names.