像F#中的Java静态导入一样?

dev*_*ium 4 .net f# functional-programming

来自Haskell,我想知道是否有办法避免List.map每次我想要使用时都要写满map.

有没有像Java的静态导入,所以我只能写map

回顾一下:

我目前要写:

List.map (fun -> 3*x) [1..10]
Run Code Online (Sandbox Code Playgroud)

但是,我希望能够写作

map (fun -> 3*x) [1..10]
Run Code Online (Sandbox Code Playgroud)

谢谢

Ste*_*sen 9

在Java中,给定一个类,mypackage.MyClass您可以使用声明"静态导入"该类中的所有静态成员import static mypackage.MyClass.*.在F#中,给定模块,MyNamespace.MyModule您可以类似地使该声明中的所有功能在没有限定的情况下可用open MyNamespace.MyModule.但正如丹尼尔指出的那样,某些模块标有RequireQualifiedAccess禁止这种情况的属性.

但是,您仍然可以在模块中对特定函数进行别名,类似于在Java中静态导入类的特定静态成员的方式.例如,在Java中,您可以执行类似的操作static import mypackage.MyClass.myMethod并在F#中执行操作let map = List.map.

除此之外,有一个很好的理由,像List,SeqArray所有需要限定访问的集合模块:它们都有一组类似的功能,只对它们的类​​型起作用,F#使用这些信息进行类型推断.我不确定细节,但Haskell在其类型系统中有一些功能map,例如,允许在不破坏类型推断的情况下在几种不同类型上使用.请注意,Seq在F#(和.NET)中有点特殊,因为它适用于实现IEnumerable<'a>包括列表和数组的接口的所有类型.因此,您可以使用别名let map = Seq.map并能够处理map所有这些集合类型,但是您将丢失这些具体实现的功能,因为它们IEnumerable<'a>是其中最低的共同点.

所以最后,在F#中,最好的办法就是map在每个集合模块中使用完全限定的函数.你得到的类型推断是一个很小的代价(我有时会想知道我是否通过类型推断来节省我输入必须限定所有这些集合函数的东西,但我相信你最终通过类型推理节省而获胜在考虑复杂的通用签名时,或许更重要的是必须推理所有这些类型的计算).

保存击键的另一个选项是通过模块别名.你可以做点什么module L = List.对于简短的常见模块名称List,我不会这样做,但我可能会这样做,ResizeArray或者也许是我自己有时冗长的模块名称.