F# Fable实现外部接口编译错误

F# Fable实现外部接口编译错误,f#,fable-f#,F#,Fable F#,TL;医生: 我试图创建一个外部接口,但我得到编译错误。我的F#技能还不能胜任这项任务 我已经写了一个Photoshop脚本,现在我正试图将该脚本转换为寓言(F#),以便我自己进行F#练习 旁注:我对F#很陌生,但我有很好的C#背景 要使用photoshop脚本库,我需要将其定义为外部接口()。为了测试的目的,我首先尝试实现一个小类。即单位价值等级(见第230页) 我的尝试: #r "node_modules/fable-core/Fable.Core.dll" open System op

TL;医生: 我试图创建一个外部接口,但我得到编译错误。我的F#技能还不能胜任这项任务


我已经写了一个Photoshop脚本,现在我正试图将该脚本转换为寓言(F#),以便我自己进行F#练习

旁注:我对F#很陌生,但我有很好的C#背景

要使用photoshop脚本库,我需要将其定义为外部接口()。为了测试的目的,我首先尝试实现一个小类。即单位价值等级(见第230页)

我的尝试:

#r "node_modules/fable-core/Fable.Core.dll"

open System
open Fable.Core

[<Global>]
module Photoshop =
    [<Erase;StringEnum>]
    type PSUnit =
        | [<CompiledName("in")>] Inches
        | [<CompiledName("ft")>] Feet
        | [<CompiledName("yd")>] Yards
        | [<CompiledName("mi")>] Miles
        | [<CompiledName("mm")>] Millimeters
        | [<CompiledName("cm")>] Centimeters
        | [<CompiledName("m")>] Meters
        | [<CompiledName("km")>] Kilometers
        | [<CompiledName("pt")>] Points
        | [<CompiledName("pc")>] Picas
        | [<CompiledName("tpt")>] TraditionalPoints
        | [<CompiledName("tpc")>] TraditionalPicas
        | [<CompiledName("ci")>] Ciceros
        | [<CompiledName("px")>] Pixels
        | [<CompiledName("%")>] Percent

    type PSUnitValue =
        abstract ``as``: PSUnit -> float
        abstract ``value``: float with get, set
        abstract ``type``: PSUnit with get, set    

    let UnitValue : PSUnitValue = jsNative

open Photoshop

let test = new UnitValue();
test.``value`` = 12.0;
test.``type`` = Unit.Centimeters

Console.WriteLine (test.``as`` PSUnit.Millimeters)

对于那些想知道
UnitValue
类的外观而不想在pdf中查找的人,我在这里用C#定义了它:

  • 您正在绑定变量
    UnitValue
    ,没有声明类型的别名(不确定这是否是目的)

  • 类型和值,就像在C#中一样,具有不同的作用域,所以就编译器而言,类型没有声明

  • jsNative
    只是“throw”的简写,它用于导入的JS构造,但不导入任何。看

  • 由于JS缺少类型,如果要实现互操作,实际上必须自己在F#中定义类型

  • 如果互操作不是目的,那么就编写一个普通的F#代码,没有任何Fable属性,Fable将处理其余部分

在此处为格式添加注释答案: UnitValue需要是函数(构造函数):

那么你可以称之为:

let test = UnitValue() 
还可以查看绑定方面的一些背景知识。

在以下人员的帮助下:

工作(ish)代码:

我不知道
export
关键字在这里做什么,也不知道为什么UnitValue没有
new
关键字,但它已编译并指向我想要的方向

向前


现在,我的输出中有
new
关键字:

let [<Global;Emit("new $0($1, $2)")>] UnitValue (v: float) (t: PSUnit): IUnitValue = jsNative

如果我选中,那么StringDecoder也被写为:
让StringDecoder:NodeStringDecoder=jsNative
和我现在做的一样。在Import属性()下,声明
如果模块或值在JavaScript中是全局可访问的,则可以使用不带参数的全局属性。
文件中未定义
UnitValue
js类型,它只是在我的photoshop js脚本中全局可访问。因此,我使用了
Global
属性。要在寓言中使用
UnitValue
,我需要为它编写一个“facade”。根据我对文档的理解,我需要创建一个外部接口。我的代码基于文档中的示例。如您所见,我的意图根本不是在输出中包含
Photoshop
模块,请查看我想要的输出以了解我的意图。我明白了混淆的原因,
UnitValue
需要是一个函数(构造函数):let UnitValue:unit->PSUnitValue=jsNative然后您可以调用它:let test=UnitValue(),因为您的隐式(main)模块是
public
,而
let
绑定是
public
fable将其声明为
export
@EugeneTolmachev,您是否有一个指针指向UnitValue缺少的新关键字?看起来UnitValue是一个函数,如果是这样,那么就不需要
new
,除非在javascript中它是一个对象。如前所述,我是一个笨蛋,也许我做错了什么?
public class UnitValue
{
    // Static baseUnit not yet implemented in Fable
    public static UnitValue baseUnit { get; set; }

    // Constructors not yet implemented in Fable
    public UnitValue(float value, string unit) { }
    public UnitValue(string valueUnit) { }

    public string type { get; set; }
    public float value { get; set; }

    public float @as(string unit) { throw new NotImplementedException(); }

    // I don't use convert in my scripts, so not yet implemented in Fable as well
    public UnitValue convert(string unit) { throw new NotImplementedException(); }
}
let UnitValue : unit->PSUnitValue = jsNative 
let test = UnitValue() 
#r "node_modules/fable-core/Fable.Core.dll"

open System
open Fable.Core

module Photoshop =
    [<StringEnum>]
    type PSUnit =
        | [<CompiledName("in")>] Inches
        | [<CompiledName("ft")>] Feet
        | [<CompiledName("yd")>] Yards
        | [<CompiledName("mi")>] Miles
        | [<CompiledName("mm")>] Millimeters
        | [<CompiledName("cm")>] Centimeters
        | [<CompiledName("m")>] Meters
        | [<CompiledName("km")>] Kilometers
        | [<CompiledName("pt")>] Points
        | [<CompiledName("pc")>] Picas
        | [<CompiledName("tpt")>] TraditionalPoints
        | [<CompiledName("tpc")>] TraditionalPicas
        | [<CompiledName("ci")>] Ciceros
        | [<CompiledName("px")>] Pixels
        | [<CompiledName("%")>] Percent

    type PSUnitValue =
        abstract ``as``: PSUnit -> float
        abstract ``value``: float with get, set
        abstract ``type``: PSUnit with get, set    
    let [<Global>] UnitValue : unit->PSUnitValue = jsNative

open Photoshop

let test = UnitValue();
test.``value`` <- 12.0;
test.``type`` <- PSUnit.Centimeters

Console.WriteLine (test.``as`` PSUnit.Millimeters)
export var test = UnitValue(null);
test.value = 12;
test.type = "cm";
console.log(test.as("mm"));
let [<Global;Emit("new $0($1, $2)")>] UnitValue (v: float) (t: PSUnit): IUnitValue = jsNative
let test = UnitValue 12.0 PSUnit.Centimeters
Console.WriteLine (test.``as`` PSUnit.Millimeters)