无法返回需要强制转换的类型(F#)

时间:2018-05-31 16:32:56

标签: types casting f#

我无法将类型的特定情况返回到另一种只想保留通用案例的类型,而不是实际实现特定示例。 (例如,与下面的类型无关,而不是以厘米为单位返回0.1,我试图返回厘米)。

我的类型定义如下:

 type UnitOfMeasure =
    | Foo of decimal
    | Bar of decimal
    | Baz of decimal

我还有:

 type BlahComponent =
    { Name : string
      Units : UnitOfMeasure }

我获得了UnitOfMeasure类型的字符串表示,我正在尝试决定我拥有哪个UnitOfMeasure(Foo,Bar或Baz)。我正在使用以下功能:

let decideUnitOfMeasure stringRepresentationOfUnitOfMeasureType = 
    match stringRepresentationOfUnitOfMeasureType with 
      | "Foo" -> Foo
      | "Bar" -> Bar 
      | "Baz" -> Baz

最后,我尝试将decisionUnitOfMeasure的返回值赋给BlahComponent

        let stringRepresentationOfUnitOfMeasureType = "Foo"
        let bomComponent = {Name = "nameString"
                            Units = decideUnitOfMeasure stringRepresentationOfUnitOfMeasureType}

尝试将determineUnitOfMeasure的返回值分配给Units会导致以下错误: 该表达式预计具有“UnitOfMeasure”类型,但类型为“(decimal - > UnitOfMeasure)”。

似乎通过UnitOfMeasure的定义,返回Foo,Bar或Baz的实际情况是不可能的,因为它需要将UnitOfMeasure转换为小数。有没有办法在没有强制转换为小数的情况下返回实际案例?

2 个答案:

答案 0 :(得分:2)

通过重新定义UnitOfMeasure来更像是一个简单的枚举,构造函数没有参数,可能是最好的服务:

type UnitOfMeasure =
    | Foo
    | Bar
    | Baz

现在您可以移动小数值,使其不是类型参数。您可以创建一个记录类型,甚至将其保存为一个简单的元组:

type BlahComponent =
    { Name : string
      Value : UnitOfMeasure * decimal }

答案 1 :(得分:2)

这不是关于施法。这只是一个类型错误。

FooUnitOfMeasure类型的构造函数。它的类型为decimal -> UnitOfMeasure。这意味着它需要decimal值并返回UnitOfMeasure

所以Foo本身不是UnitOfMeasure,而是Foo 1m。您的Units字段实际上也存储了该号码,但您没有提供该号码。

这解释了您看到此错误的原因。 Chad Gilbert的答案提供了一种可能的替代方法,但最好的方法实际上取决于你想要做的事情。