F# 创建包含1项的序列的最佳方法
在F#中,我可以通过F# 创建包含1项的序列的最佳方法,f#,sequence,F#,Sequence,在F#中,我可以通过 seq [42] // inefficient, since a list is created seq { yield 42} // verbose, would prefer { 42 } or seq { 42 } seq { 42 .. 42 } // bizarre 虽然我觉得这有点奇怪,但我很好奇是否有人知道一种简单有效的方法。 或者:为什么 { 42 } // invalid syntax. in other words, not
seq [42] // inefficient, since a list is created
seq { yield 42} // verbose, would prefer { 42 } or seq { 42 }
seq { 42 .. 42 } // bizarre
虽然我觉得这有点奇怪,但我很好奇是否有人知道一种简单有效的方法。
或者:为什么
{ 42 } // invalid syntax. in other words, not a valid sequence expression
无效?您可以使用:
Seq.singleton 42
如果您需要一个真正的序列(即
IEnumerable
,其项是惰性创建的),那么seq{yield}
可能是最简洁的语法
如果您不需要仅在消费项目时对其进行评估(急切评估是可以的),那么您可以使用Seq.singleton
函数
如果您只需要实现IEnumerable
,您可以通过使用列表或数组构造函数来实现更短的语法:[]
或[| |]
,不同之处在于数组构造函数在这种情况下可能更有效
{}
语法不起作用,因为没有创建序列的特殊语法(例如,Python中的a)。seq{yield}
是一个函数,它必须遵循几个规则,其中之一是它必须说明它定义了什么类型的计算(seq
部分这样说)。如果您想省略seq
部分,您需要F#来支持通用计算表达式,我认为这目前是不可能的(并且可能需要一些类似于typeclass的功能)。[42]比seq[42]短,但仍然创建了一个不必要的列表仍然创建一个IEnumerable
实例,并有一些隐藏的方法调用。如果效率是您的一个问题,我建议您一般不要使用seq
表达式。确实如此。您可能会理解,我并不总是创建单例,所以让我们继续讨论这个非常简单的问题。实际上,[x]是外观最好的替代方案,我考虑过使用它,而不管添加了什么列表创建。但这样做,类型推断就会陷入困境,另一方面需要类型注释,这也不太好。因此,最终决定使用Seq.singleton作为惯用的编码风格。显然,这是f#的预期方式。虽然{42}更自负,但singleton冗长但富于表现力。