2016-10-06 19 views
5

我有困難提到Fable中的無參數函數。寓言F#到Javascript:無參數函數被給予參數時,被引用

有了這個例子:

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庫中的函數,其預期的功能,作爲一個參數被傳遞)


編輯:

背景

以上就是我認爲是一個最小的,可覈查的,再現我的問題,但是,評論後,我想這可能是有用的提供觸摸爲什麼這是造成問題的詳細內容。我真正想做的是使用Fable的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(); 
}); 

然後我的例子按預期工作。

我真的很想知道是否有以避免寓言編譯器生成該參數的方法。我99%肯定這減少了同樣的問題,在我原來的問題,但我已經包含這一附加背景下,以更好地解釋爲什麼這是一個問題

+4

不確定這是否相關,但該函數並非真正無參數,它具有單個單元類型的單個參數。 –

+0

是的,好點,但它預期地映射了原來的「無參數」功能 - 只是在參考該功能時出現問題 –

+0

究竟是什麼問題?我能用'arg00_'看到的唯一問題是,如果將它傳遞給一些使用'f.length'獲取聲明數量的參數的javascript代碼,這是非常令人沮喪的做法。否則它不應該改變任何東西。 – Tarmil

回答

7

非常感謝您的提問和詳細的解釋。這裏有兩件事情有點棘手,是由F#編譯器和Fable的優化造成的。

  • 在由F#編譯器提供的AST,方法(即是一種類型或模塊的成員函數)被編譯爲通常方法如C#。這是爲了優化。然而,當你創建一個匿名lambda或引用一個方法時,F#編譯器將保持F#語義,也就是說,所有函數都有一個參數(正如John Palmer所說,unit也是一個參數),並且可以咖喱。

好的,這個信息只是爲了澄清爲什麼F#編譯器/寓言代表方法和lambda表達不同。讓我們繼續討論無參數函數的問題:顯而易見的解決方案當然是刪除F#編譯器爲接受unit的函數生成的參數(因爲它已經爲方法完成了)。事實上,我也因爲這個問題而與像摩卡這樣的圖書館有過問題。

我曾嘗試在開始時刪除unit參數,但由於此原因,在某些情況下我失敗了。 TBH,我現在不記得確切地說哪些測試失敗了,但是由於期望總會有一個參數,在某些情況下,當刪除參數時,函數組合或內聯失敗。

其他嘗試修改JS運行時中F#函數的語義總是失敗,因爲它們沒有涵蓋所有場景。但是,對於代表(System.Func<>),我們可以更加寬容,因爲通常認爲這些函數更像C#或F#等語言中的函數。我可以嘗試刪除只爲代表的單位參數,看看會發生什麼:)

有關發送F#函數到JS代碼的更多信息,您可以檢查documentation

UPDATE:從頭開始,請嘗試[email protected][email protected]。這個版本消除了unit的論點,解決方案實際上比我想象的更簡單,並且(希望)不應該對現有項目造成問題。 (有關方法和lambda表達式的解釋仍然適用。)