我正在使用F#规范的最终工作流程的修改版本,以便在Xbox上进行开发.看来,Xbox上的.net框架不支持尾调用.因此,我必须在编译时禁用尾调用优化.
虽然最初似乎这种限制会阻止在计算表达式中使用任何形式的循环,但我最初认为"步进"可以避免这个问题:计算表达式中的递归函数f不直接调用自身,而是返回一个包含lambda的最终值,该lambda调用f.
实验表明我对while循环是正确的(它们在计算表达式中使用时不会导致堆栈溢出),但不是关于递归函数.
为了澄清,这有效:
// Wait until "start" or "A" is pressed on one of the gamepads.
// Set "player" when that happens.
let player : PlayerIndex option ref = ref None
while (!player).IsNone do
for p in all_players do
let state = GamePad.GetState(p)
if state.IsConnected
&& (state.Buttons.Start = ButtonState.Pressed
|| state.Buttons.A = ButtonState.Pressed) then
player := Some p
do! sys.WaitNextFrame()
Run Code Online (Sandbox Code Playgroud)
这会导致堆栈溢出:
// Wait until "start" is pressed on the controlling gamepad.
let rec wait() = task {
input.Update()
if …
Run Code Online (Sandbox Code Playgroud) 这是我到目前为止:
type Maybe<'a> = option<'a>
let succeed x = Some(x)
let fail = None
let bind rest p =
match p with
| None -> fail
| Some r -> rest r
let rec whileLoop cond body =
if cond() then
match body() with
| Some() ->
whileLoop cond body
| None ->
fail
else
succeed()
let forLoop (xs : 'T seq) f =
using (xs.GetEnumerator()) (fun it ->
whileLoop
(fun () -> it.MoveNext())
(fun () -> it.Current |> f) …
Run Code Online (Sandbox Code Playgroud) 在将项目转换为可移植类库之后,使用xna针对xbox360的F#代码无法编译.
let thread = Thread(fun () ->
setAffinity()
Run Code Online (Sandbox Code Playgroud)
线程得到红色波形,错误信息说
错误1此类型没有可访问的对象构造函数
果然,如果我在对象资源管理器中查看mscorlib,该类型没有构造函数.然而根据MSDN,构造函数存在于xbox和PCL中.
编辑:我尝试使用C#PCL,我得到了同样的错误.
type T() =
static member (~%)(t : T) = t
let t = T()
let t' = %t // FAILS
Run Code Online (Sandbox Code Playgroud)
错误消息说t
预计是类型Quotation.Expr<'a>
.%是一个所谓的有效前缀运算符,但它是否可以实际使用它?
我想写的是:
type A() =
interface IX with ...
interface IY with ...
type B() =
interface IX with ...
interface IY with ...
let mk t : 'T when 'T :> IX and 'T :> IY =
match t with
| Choice1 -> new A()
| Choice2 -> new B()
Run Code Online (Sandbox Code Playgroud)
注意mk的返回类型的类型约束.虽然它没有编译,编译器抱怨它不能将A和B转换为'T.