F# F中C#类的并集声明困难#

F# F中C#类的并集声明困难#,f#,F#,我使用的是C#weather library,它提供了几个不同时间段的天气预报课程(例如,每小时、每天、“现在”),这些课程都包含类似的数据 我正在尝试编写可以接受这些类中任何一个的函数,但是我遇到了一些编译错误(如下),我不明白: 对于FS0001错误,为什么与预测联合类型匹配的对象不满足getTemp函数?为什么在每种情况下都需要不同的参数类型 对于FS0019错误,它指的是什么构造函数?为什么它希望我向这个构造函数提供一个参数 下面是一些示例代码: open ForecastIO typ

我使用的是C#weather library,它提供了几个不同时间段的天气预报课程(例如,每小时、每天、“现在”),这些课程都包含类似的数据

我正在尝试编写可以接受这些类中任何一个的函数,但是我遇到了一些编译错误(如下),我不明白:

  • 对于FS0001错误,为什么与预测联合类型匹配的对象不满足
    getTemp
    函数?为什么在每种情况下都需要不同的参数类型

  • 对于FS0019错误,它指的是什么构造函数?为什么它希望我向这个构造函数提供一个参数

  • 下面是一些示例代码:

    open ForecastIO
    
    type Forecast = 
        | Currently of ForecastIO.Currently
        | HourForecast of ForecastIO.HourForecast
    
    let getTemp forecast =
        match forecast with
            | Currently -> forecast.temperature
            | HourForecast -> forecast.temperature
        |> float
    
    let forecastForDate date = 
        let request = new ForecastIORequest("api_key", 35.780556f, -78.638889f, date, Unit.us);
        request.Get ()
    
    let test () = 
        let baseDate = System.DateTime.Parse "2014-06-12 22:00:00"
        let forecast = forecastForDate baseDate
    
        forecast
        |> (fun r -> r.currently)
        |> getTemp
        |> printfn "%f"
    
        forecast
        |> (fun r -> r.hourly.data.[0])
        |> getTemp
        |> printfn "%f"
    
    test ()
    
    这是我的编译器输出:

    /tmp/forecast.io/test2.fs(9,15): error FS0019: This constructor is applied to 0 argument(s) but expects 1
    
    /tmp/forecast.io/test2.fs(23,12): error FS0001: Type mismatch. Expecting a
        Currently -> 'a    
    but given a
        Forecast -> float    
    The type 'Currently' does not match the type 'Forecast'
    
    /tmp/forecast.io/test2.fs(28,12): error FS0001: Type mismatch. Expecting a
        HourForecast -> 'a    
    but given a
        Forecast -> float    
    The type 'HourForecast' does not match the type 'Forecast'
    

    效果更好吗

    let getTemp forecast =
        match forecast with
            | :? Currently as c -> c.temperature
            | :? HourForecast as h -> h.temperature
        |> float
    

    效果更好吗

    let getTemp forecast =
        match forecast with
            | :? Currently as c -> c.temperature
            | :? HourForecast as h -> h.temperature
        |> float
    

    分解DU时,需要指定构造函数参数的名称(即构造DU案例所需的参数)。在这种情况下,您不想使用它们,因此可以按如下方式将它们清空:

    let getTemp forecast =
        match forecast with
            | Currently _ -> forecast.temperature
            | HourForecast _ -> forecast.temperature
        |> float
    

    分解DU时,需要指定构造函数参数的名称(即构造DU案例所需的参数)。在这种情况下,您不想使用它们,因此可以按如下方式将它们清空:

    let getTemp forecast =
        match forecast with
            | Currently _ -> forecast.temperature
            | HourForecast _ -> forecast.temperature
        |> float
    

    有几个不同的问题。一个是@ @ MyDooSbox提到的——如果DU案例有字段,则需要在模式匹配中考虑它们,或者用<代码> < <代码>忽略它们,或者捕获到某个标识符。

    不过,主要的问题是,您没有在任何地方创建DU的实例。您的预测对象的
    .Current
    属性可能是
    ForecastIO.Current
    .hourly.data类型。[0]
    ForecastIO.HourForecast
    类型,但这并不意味着您可以从
    预测中获取这些值并将其视为案例。您需要显式构造所需的案例:

      forecast
      |> (fun r -> Currently(r.currently))
      |> getTemp
      |> printfn "%f"
    
      forecast
      |> (fun r -> HourForecast(r.hourly.data.[0]))
      |> getTemp
      |> printfn "%f"
    
    如果您不想定义DU,而只是想根据输入的类型进行模式匹配,您可以按照@Jan的建议进行操作,甚至不必定义DU:

    let getTemp forecast =
        match forecast with
            | :? ForecastIO.Currently as c -> c.temperature
            | :? ForecastIO.HourForecast as h -> h.temperature
        |> float
    

    有几个不同的问题。一个是@ @ MyDooSbox提到的——如果DU案例有字段,则需要在模式匹配中考虑它们,或者用<代码> < <代码>忽略它们,或者捕获到某个标识符。

    不过,主要的问题是,您没有在任何地方创建DU的实例。您的预测对象的
    .Current
    属性可能是
    ForecastIO.Current
    .hourly.data类型。[0]
    ForecastIO.HourForecast
    类型,但这并不意味着您可以从
    预测中获取这些值并将其视为案例。您需要显式构造所需的案例:

      forecast
      |> (fun r -> Currently(r.currently))
      |> getTemp
      |> printfn "%f"
    
      forecast
      |> (fun r -> HourForecast(r.hourly.data.[0]))
      |> getTemp
      |> printfn "%f"
    
    如果您不想定义DU,而只是想根据输入的类型进行模式匹配,您可以按照@Jan的建议进行操作,甚至不必定义DU:

    let getTemp forecast =
        match forecast with
            | :? ForecastIO.Currently as c -> c.temperature
            | :? ForecastIO.HourForecast as h -> h.temperature
        |> float
    

    你失去了拥有歧视性联盟的所有好处,但是是的,它是有效的。你失去了拥有歧视性联盟的所有好处,但是是的,它是有效的。