这是我的问题:
let foo =
match bar with
| barConfig1 -> configType1(devices:DeviceEntities,DeviceStartIndex,inputStartIndex,outputStartIndex)
| barConfig2 -> configType2(devices:DeviceEntities,DeviceStartIndex,inputStartIndex,outputStartIndex)
| barConfig3 -> configType3(devices:DeviceEntities,DeviceStartIndex,inputStartIndex,outputStartIndex)
| barConfig4 -> configType4(devices:DeviceEntities,DeviceStartIndex,inputStartIndex,outputStartIndex)
我希望foo的类型由match语句决定,但它总是将foo设置为第一种类型。
type bar =
|barConfig1
|barConfig2
|barConfig3
|barConfig4
答案 0 :(得分:4)
在F#中,没有语句,只有表达式,每个表达式都必须具有单一的具体类型。 match
块也是一个表达式,这意味着它必须具有单个具体类型。接下来是匹配的每个案例都必须具有相同的类型。
也就是说,这样的东西不是有效的F#:
let foo = // int? string?
match bar with // int? string?
| Int -> 3 // int
| String -> "Three" // string
在这种情况下,类型推断机制将期望匹配的类型与第一个case的类型相同 - int,并且当它在第二个中看到字符串时最终会混淆。在您的示例中,同样的事情发生 - 类型推断要求所有情况都返回configType1。
解决这个问题的方法是将值转换为常用的超类型或接口类型。因此,对于您的情况,假设configTypes实现了一个通用的IConfigType接口:
let foo = // IConfigType
let arg = (devices:DeviceEntities,DeviceStartIndex,inputStartIndex,outputStartIndex)
match bar with
| barConfig1 -> configType1(arg) :> IConfigType
| barConfig2 -> configType2(arg) :> IConfigType
| barConfig3 -> configType3(arg) :> IConfigType
| barConfig4 -> configType4(arg) :> IConfigType
答案 1 :(得分:0)
如果输出类型的个案数量有限,您也可以将其作为一个有区别的联合:
type ConfigType =
| ConfigType1 of configType1
| ConfigType2 of configType2
| ConfigType3 of configType3
| ConfigType4 of configType4``
let foo =
match bar with
| barConfig1 -> ConfigType1 <| configType1(devices:DeviceEntities,DeviceStartIndex,inputStartIndex,outputStartIndex)
| barConfig2 -> ConfigType2 <| configType2(devices:DeviceEntities,DeviceStartIndex,inputStartIndex,outputStartIndex)
| barConfig3 -> ConfigType3 <| configType3(devices:DeviceEntities,DeviceStartIndex,inputStartIndex,outputStartIndex)
| barConfig4 -> ConfigType4 <| configType4(devices:DeviceEntities,DeviceStartIndex,inputStartIndex,outputStartIndex)``
或者,如果它们都实现了一个接口或继承了一些基类,那么你可以向上转发,就像scrwtp的回答一样。