所以我的意思是循环展开就像
Write "Hello" |> Repeat 5
Run Code Online (Sandbox Code Playgroud)
- >>>
Write "Hello"
Write "Hello"
Write "Hello"
Write "Hello"
Write "Hello"
Run Code Online (Sandbox Code Playgroud)
据我所知,这是一些优化,如果可能在.NET上,我感到很有趣
顺便说一下 - 简单地说为什么我必须在[0..4]中使用...如果我真的不是这个[0..4]并且我真的不需要这个...
F#语言不直接支持这种形式的元编程.你要求的通常被称为多阶段编程,并且有支持它的基于ML的语言(例如搜索MetaML).在这些语言中,您可以使用已编译的代码进行操作,并(例如)展开循环.
这种有限形式可以使用引用在F#中完成.但它不是很实用,因为F#引用编译器会生成较慢的代码(因此它肯定不能用作优化).
然而,仅仅是为了好奇,这里是如何使用F#PowerPack中的引用和引用编译器来实现这一点:
#r @"FSharp.PowerPack.Linq.dll"
open Microsoft.FSharp.Linq.QuotationEvaluation
// Generate quotation that contains 5 prints followed by expression that returns unit
let unrolled = [ 1 .. 5 ] |> List.fold (fun expr _ ->
<@ printfn "Hello"; %expr @>) <@ () @>
// Compile the function once & run it two times
let f = unrolled.Compile()
f()
f()
Run Code Online (Sandbox Code Playgroud)
...正如我所提到的,这对于优化来说没有用,因为该Compile方法产生的代码很慢,但在其他一些场景中它很有用.
您可以编写for _ in 0..4以指示您不需要循环变量的值.
在F#语言级别上执行类似循环展开的操作需要支持宏.在像Lisp或Clojure这样的语言中你可以做到这一点.但通常最好让编译器或运行时担心这一点.
在IL级别,您可以使用System.Reflection.Emit命名空间的类(或使用像Cecil这样的库)来实现循环展开之类的事情.