Favascript F#to Javascript:无参数函数在引用时被赋予参数

时间:2016-10-06 09:45:54

标签: f# fable-f#

我在寓言中引用无参数函数时遇到了困难。

通过这个例子:

let f1 () = 
    1

let someRefTof1 = f1

我希望生成的js看起来像这样:

function f1() {
    return 1;
}

var someRefTof1 = f1;

但实际得到的是:

function f1() {
    return 1;
}

var someRefTof1 = exports.someRefTof1 = function someRefTof1(arg00_) {
    return f1(arg00_);
};

我不清楚arg00_的目的或如何避免它被生成?

(作为一个背景,我正在努力调用外部js库中的函数,该函数需要将函数作为参数传递)

编辑:

背景

以上是我认为是对我的问题的最小化,可验证的再现,但是在评论之后,我认为提供更多关于为什么会导致问题的背景可能是有用的。我实际上要做的是使用寓言中的angularjs。

所以我的例子看起来更像是这样:

let app = AngularFable.NgFable.angular.``module``("app",[||])

type TestCtrl() = 
    member this.Val1() = "boom";

app?controller("test", TestCtrl)

汇编为:

var app = exports.app = angular.module("app", []);

var TestCtrl = exports.TestCtrl = function () {
    function TestCtrl() {
        _classCallCheck(this, TestCtrl);
    }

    TestCtrl.prototype.Val1 = function Val1() {
        return "boom";
    };

    return TestCtrl;
}();

_fableCore.Util.setInterfaces(TestCtrl.prototype, [], "App.TestCtrl");

app.controller("test", function (unitVar) {
    return new TestCtrl();
});

unitVar是此示例中引入的有问题的参数。当我在我的html中使用它时,例如:

  <div ng-app="app">
    <div ng-controller="test as vm">
      {{vm.Val1()}}
    </div>
  </div>

我遇到unknown provider错误,而如果我只是更改已编译的javascript以从最后一行删除unitVar参数,如下所示:

app.controller("test", function () {
    return new TestCtrl();
});

然后我的例子按预期工作。

我真的很想知道是否有办法避免让Fable编译器生成此参数。我99%肯定这会减少与原始问题相同的问题但我已经包含了这个额外的背景,以便更好地解释为什么这是一个问题

1 个答案:

答案 0 :(得分:8)

非常感谢您提出的问题和详细解释。这里有两件事有点棘手,是由F#编译器和Fable的优化引起的。

  • 在F#编译器提供的AST中,方法(作为类型或模块成员的函数)被编译为通常的方法,如在C#中。这是为了优化。
  • 但是,当您创建匿名lambda或引用方法时,F#编译器将保留F#语义,即所有函数都有一个参数(正如John Palmer所说,unit是一个参数(也)可以咖喱。

好的,这个信息只是为了弄清楚为什么F#编译器/ Fable以不同的方式表示方法和lambda。让我们讨论无参数函数的问题:显而易见的解决方案当然是删除F#编译器为接受unit的函数生成的参数(因为它已经为方法做了)。事实上,由于这个原因,我也遇到像Mocha这样的图书馆的问题。

我确实尝试在开头删除unit参数,但由于这个原因我在某些情况下失败了。 TBH,我现在不记得究竟哪些测试失败了,但是由于期望总会有一个参数,在某些情况下,当unit参数被移除时,函数组合或内联失败。

在JS运行时中修改F#函数语义的其他尝试总是失败,因为它们不包括所有场景。但是,我们可以对代理(System.Func<>)更宽容,因为通常可以安全地假设这些代理应该更像C#或F#等语言中的函数。我可以尝试为代表删除单位参数,看看会发生什么:)

有关将F#函数发送到JS代码的更多信息,您可以查看documentation

更新:抓住这一切,请尝试fable-compiler@0.6.12和fable-core@0.6.8。这个版本消除了unit个参数,解决方案实际上比我想象的更简单,并且(希望)不应该与现有项目产生问题。 (关于方法和lambdas编译的不同的解释仍然适用。)