0

我遇到Function了需要传递给JQueryAnimationOptions对象的这种类型。我通常会将 lambda 传递给回调,但这些似乎不兼容。我查找了在 FunScript 存储库中可以找到的每个示例。并且找不到任何解决方法。

它还说Function当用作 return 语句时 the 实际上是一个接口(为了什么?)Error: Invalid use of interface type

那么如何传递这种Function类型的回调参数呢?

在此处输入图像描述

编码:

[<FunScript.JS>]
module Main

open FunScript
open FunScript.TypeScript

let sayHelloFrom (name:string) = 
    Globals.window.alert("Hello, " + name)

let jQuery (selector:string) = Globals.jQuery.Invoke selector

let main() = 
    let options = createEmpty<JQueryAnimationOptions>()
    options.duration <- 3000
    options.complete <- (fun _ -> sayHelloFrom("F#")) 
    let properties = createEmpty<Object>()
    properties.Item("opacity") <- 1
    let mainContent = jQuery "#mainContent"
    mainContent.animate(properties, options) |> ignore
    mainContent.click(fun e -> sayHelloFrom("F#") :> obj)
4

2 回答 2

2

在 F# 和 C# 之间传递 lambda 时,这或多或少的工作方式与您所期望的一样。在 F# 中,函数可以被柯里化,而在 C#(和 JavaScript)中则不能。因此,当您需要将 lambda 从 F# 发送到 C# 时,您需要先将其转换。在 F# 中,这是通过像这样包装 lambda 来完成的:

open System.Linq
open System.Collections.Generic

let ar = [|1;2;3|]
let f = fun (x: int) (y: int) -> x + y
let acc = ar.Aggregate( System.Func<int,int,int>(f) )

实际上,F# 编译器大多数时候都可以推导出类型,所以你只需要写:System.Func<_,_,_>(f). 此外,当将 F# lambda 传递给需要 C# lambda 的方法时,编译器会自动为您进行包装。那么前面的例子就变成了:

let ar = [|1;2;3|]
let acc = ar.Aggregate( fun x y -> x + y )

(当然,在这种情况下,最好使用惯用的 Array.reduce。这只是一个人为的例子。)

这在使用 FunScript 与 JS 交互时完全相同。您唯一需要注意的是 F# lambda 是如何转换为 JS 的。为了允许柯里化,具有两个或多个参数的 lambdafun x y -> x + y变为:

function (x) {
    return function (y) {
        return x + y;
    }
}

这可能是一个问题,因为本机 JS 将期望以下签名:function (x, y). 在这种情况下,您必须在System.Func<_,_,_>()与 C# 交互时用 as 包装 lambda(请记住,如果您将 lambda 传递给方法,则会自动完成)。

然而,只有一个参数的 lambdas 并不认为有任何问题:fun x -> x*x变成function (x) { return x*x; }. 在这种情况下,您不需要包装它们(无论如何这样做并没有什么坏处),并且unbox在必要时用于安抚 F# 编译器就足够了。请注意,FunScript 编译器会忽略unbox最终的 JS 代码,因此在运行时根本不会进行类型检查。

我希望解释清楚。如果不是,请添加评论,我将编辑答案。

于 2015-01-07T09:39:39.087 回答
0

没关系,我找到了解决方案,我不得不unbox使用 lambda:

options.complete <- unbox<Function> (fun _ -> sayHelloFrom("F#"))
于 2015-01-05T10:53:17.757 回答