F# Constructed Type 语法是否特殊?
Is F# Constructed Type syntax special?
我对 F# 的“构造类型”语法很好奇。已记录 here.
type-argument generic-type-name
or
generic-type-name
结合以下例子:
int option
string list
int ref
option<int>
list<string>
ref<int>
Dictionary<int, string>
我很好奇“向后”语法是否有任何特殊之处,参数在类型之前,或者它是否只是具有一个参数的泛型类型的糖。以下是有效的:
type 'a MyOption = // MyOption<'a> also works
| MySome of 'a
| MyNone
但我无法让它使用多个类型参数。为什么 F# 开发人员更喜欢将这种语法用于具有一个参数的类型?是否有可能或希望让它与两个一起工作?
向后语法是 legacy from OCaml。就个人而言,我从不使用它。如果你真的想要,你可以像这样使用多个类型参数:
type MyMap = (int, string) Map
然而,这会产生尖锐的警告(可能很快会变成 an error):
This construct is for ML compatibility. The syntax '(typ,...,typ) ident' is not used in F# code. Consider using 'ident<typ,...,typ>' instead. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'.
最重要的是,我建议始终使用 .NET 语法:MyOption<'a>
而不是 'a MyOption
。
为什么 F# 开发人员更喜欢这种只有一个参数的类型的语法?
并非所有人都如此。我喜欢 F# 并且对它敬畏,但发现 OCaml 风格让人分心。
当两种样式混合时,它会变得特别混乱 - 比较 Async<Result<int,string list>> list
和 List<Async<Result<int,List<string>>>>
的可读性。
这是一个线程,其中包含来自 fslang suggestions 双方的一些论点,我认为这导致了 OCaml-style 除了 list
、option
和其他几个。
我感到遗憾的是,OCaml 样式在各种样式指南中被指定为首选选项(对于这些类型),并在整个核心库中使用,同时有如此强大的动力使该语言更易于访问给新人。正如这个问题中记录的那样,它肯定会增加学习曲线,
here,
,
here,
,
here.
[OCaml 样式命名]是否可以或需要使用两个[类型参数]?
我认为一个更好的问题是:“是否可以只使用 .NET 样式?”。
不幸的是,工具以声明的方式显示类型,并且核心库始终使用 OCaml 样式。我有 asked Rider about always showing declarations .NET style in code vision, who referred me to FSharp compiler services。我还没有(还)进一步调查那条途径。
在我们自己的代码中,我们已经开始覆盖 F# 和其他库附带的函数的 OCaml 签名,例如:
[<AutoOpen>]
module NoCaml =
module List =
/// Returns a new collection containing only the elements of the collection for which the given predicate returns "true"
let filter = List.filter : ('a -> bool) -> List<'a> -> List<'a>
/// val groupBy : projection:('T -> 'Key) -> list:'T list -> ('Key * 'T list) list (requires equality and equality) 'T is 'a 'Key is 'b Applies a key-generating function to each element of a list and yields a list of unique keys. Each unique key contains a list of all elements that match to this key.
let groupBy = List.groupBy : ('a -> 'b) -> List<'a> -> List<'b * List<'a>>
// etc.
这几乎解决了所有情况(一些例外情况,如使用 []
的列表构造仍然存在,需要在声明时覆盖)。
我不确定这对运行时的性能有什么影响 - 希望额外的函数调用被优化掉。
我对 F# 的“构造类型”语法很好奇。已记录 here.
type-argument generic-type-name
or
generic-type-name
结合以下例子:
int option
string list
int ref
option<int>
list<string>
ref<int>
Dictionary<int, string>
我很好奇“向后”语法是否有任何特殊之处,参数在类型之前,或者它是否只是具有一个参数的泛型类型的糖。以下是有效的:
type 'a MyOption = // MyOption<'a> also works
| MySome of 'a
| MyNone
但我无法让它使用多个类型参数。为什么 F# 开发人员更喜欢将这种语法用于具有一个参数的类型?是否有可能或希望让它与两个一起工作?
向后语法是 legacy from OCaml。就个人而言,我从不使用它。如果你真的想要,你可以像这样使用多个类型参数:
type MyMap = (int, string) Map
然而,这会产生尖锐的警告(可能很快会变成 an error):
This construct is for ML compatibility. The syntax '(typ,...,typ) ident' is not used in F# code. Consider using 'ident<typ,...,typ>' instead. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'.
最重要的是,我建议始终使用 .NET 语法:MyOption<'a>
而不是 'a MyOption
。
为什么 F# 开发人员更喜欢这种只有一个参数的类型的语法?
并非所有人都如此。我喜欢 F# 并且对它敬畏,但发现 OCaml 风格让人分心。
当两种样式混合时,它会变得特别混乱 - 比较 Async<Result<int,string list>> list
和 List<Async<Result<int,List<string>>>>
的可读性。
这是一个线程,其中包含来自 fslang suggestions 双方的一些论点,我认为这导致了 OCaml-style 除了 list
、option
和其他几个。
我感到遗憾的是,OCaml 样式在各种样式指南中被指定为首选选项(对于这些类型),并在整个核心库中使用,同时有如此强大的动力使该语言更易于访问给新人。正如这个问题中记录的那样,它肯定会增加学习曲线,
here,
[OCaml 样式命名]是否可以或需要使用两个[类型参数]?
我认为一个更好的问题是:“是否可以只使用 .NET 样式?”。
不幸的是,工具以声明的方式显示类型,并且核心库始终使用 OCaml 样式。我有 asked Rider about always showing declarations .NET style in code vision, who referred me to FSharp compiler services。我还没有(还)进一步调查那条途径。
在我们自己的代码中,我们已经开始覆盖 F# 和其他库附带的函数的 OCaml 签名,例如:
[<AutoOpen>]
module NoCaml =
module List =
/// Returns a new collection containing only the elements of the collection for which the given predicate returns "true"
let filter = List.filter : ('a -> bool) -> List<'a> -> List<'a>
/// val groupBy : projection:('T -> 'Key) -> list:'T list -> ('Key * 'T list) list (requires equality and equality) 'T is 'a 'Key is 'b Applies a key-generating function to each element of a list and yields a list of unique keys. Each unique key contains a list of all elements that match to this key.
let groupBy = List.groupBy : ('a -> 'b) -> List<'a> -> List<'b * List<'a>>
// etc.
这几乎解决了所有情况(一些例外情况,如使用 []
的列表构造仍然存在,需要在声明时覆盖)。
我不确定这对运行时的性能有什么影响 - 希望额外的函数调用被优化掉。