【问题标题】:Providing a function that is bound by 3rd party scipt提供受第 3 方脚本约束的功能
【发布时间】:2017-08-21 05:01:09
【问题描述】:

我正在尝试在 Fsharp 中编写一个 riot 标签,但如果不更改 riot,我无法这样做。

在 JavaScript 中我应该 provide a function like:

function(opts) {
  this.on("update",function(opts){
    this.opts = opts || this.opts;
  });
}

然后riot 将call this function 使用Function.prototype.call:

if (impl.fn) { impl.fn.call(this, opts); }

在 F# 中,我尝试了以下操作:

[<Emit("this")>]
let isThis (x: 'a) : obj = jsNative

let bind fn =
  fun o ->
    fn (isThis 1) o 

[<Emit("$0 === undefined")>]
let isUndefined (x: 'a) : bool = jsNative

bind
  (
    fun me opts ->
      me?on(
        "update"
        ,(
          fun opts ->
            if not (isUndefined opts) then
              me?opts <- opts
              ()
        )
      )
  )

但是;绑定函数被转译为:

export function bind(fn, o) {
  return fn(this)(o);
}

当我想咖喱时不咖喱,我正在寻找的输出是:

export function bind(fn) {
  return function(o){
    return fn(this)(o);
  }
}

我可以让它工作的唯一方法是将 riot.js 更改为:

if (impl.fn) { impl.fn(this)(opts); }

并通过以下方式在 F# 中提供我的功能:

fun me opts ->
  me?on(
    "update"
    ,(
      fun opts ->
        if not (isUndefined opts) then
          me?opts <- opts
          ()
    )
  )

更改第 3 方库以满足转译器生成的代码并不理想。转译器有没有办法生成我正在寻找的输出?

[更新]

不需要更改第 3 方代码的更好方法是提供绑定函数作为第 3 方 JavaScript:

然后导入它并在你的模板代码文件中使用绑定:

let JSI = 
  bind<(obj -> obj -> unit) -> obj>
    "../../../js/3rd/JSI.js"
bind
  (
    fun me opts ->
      me?on(
        "update"
        ,(
          fun opts ->
            if not (isUndefined opts) then
              me?opts <- opts
              ()
        )
      )
  )

【问题讨论】:

    标签: f# riot.js fable-f#


    【解决方案1】:

    你遇到了 Fable 的 automatic uncurrying。您需要做的是将 F# 函数替换为 System.Func 代表,以防止 Fable 取消柯里化。

    我能够非常接近这个:

    [<Emit("this")>]
    let jsThis : obj = jsNative
    
    let bind (fn : Func<obj, (obj -> obj)>) = 
      Func<_, _> (fun o -> fn.Invoke(jsThis) o)
    

    生成的 JavaScript:

    export function bind(fn) {
        return (o) => fn(this)(o);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多