我想在F#中編寫一個方法,它根據傳入方法的值的類型返回一個泛型類型的新實例。在FSI:類型不匹配錯誤。 F#類型推斷失敗?
open System.Collections.Generic
type AttributeIndex<'a>() =
inherit SortedDictionary<'a, HashSet<int array>>()
let getNewIndexForValue (value: obj) : AttributeIndex<_> =
match value with
| :? string -> new AttributeIndex<string>()
| :? int -> new AttributeIndex<int>()
| :? float -> new AttributeIndex<float>()
| :? bool -> new AttributeIndex<bool>()
| _ -> failwith "bad value type"
let someIndexes = [
getNewIndexForValue 9;
getNewIndexForValue "testString";
getNewIndexForValue false;
getNewIndexForValue 5.67;
]
someIndexes;;
這不會錯誤編譯
error FS0001: Type mismatch. Expecting a AttributeIndex<string>
but given a AttributeIndex<int>
The type 'string' does not match the type 'int'
我似乎無法弄清楚如何獲得屬性的一個實例,與基於的類型的Param類型傳遞給函數的值參數。我已經嘗試了其他一些變體,但都導致相同類型的不匹配錯誤。任何幫助將不勝感激。謝謝!!
UPDATE:
感謝您的答案。我現在明白了。所以現在我試圖讓我的'getNewIndexForValue'返回一個非泛型的基礎AttributeIndex類。我在C#中實現這一點,它編譯和運行如我所料:
using System;
using System.Collections.Generic;
namespace Example {
public class AttributeIndexBase : SortedDictionary<object, HashSet<int[]>> { }
public class AttributeIndex<T> : AttributeIndexBase {
public void AddToIndex(T indexValue, int[] recordKey) {
if (!this.ContainsKey(indexValue)) {
this.Add(indexValue, new HashSet<int[]> { recordKey });
}
else {
this[indexValue].Add(recordKey);
}
}
}
class Program {
static int Main(string[] args) {
var intIdx = GetIndexForValue(32);
var boolIdx = GetIndexForValue(true);
var doubleIdx = GetIndexForValue(45.67);
var someIndexes = new List<AttributeIndexBase> {
intIdx,
boolIdx,
doubleIdx
};
return 0;
}
static AttributeIndexBase GetIndexForValue(object value) {
switch (value.GetType().Name.ToLower()) {
case "int32" :
return new AttributeIndex<int>();
case "single" :
return new AttributeIndex<float>();
case "double" :
return new AttributeIndex<double>();
case "boolean" :
return new AttributeIndex<bool>();
default :
throw new ArgumentException("The type of the value param is not allowed", "value");
}
}
}
}
然而,試圖端口這F#不工作:
module example
open System
open System.Collections.Generic
type AttributeIndexBase() =
inherit SortedDictionary<obj, HashSet<int array>>()
type AttributeIndex<'a>() =
inherit AttributeIndexBase()
let getNewIndexForValueType (value: ValueType) : AttributeIndexBase =
match value with
| :? int -> new AttributeIndex<int>()
| :? float -> new AttributeIndex<float>()
| :? bool -> new AttributeIndex<bool>()
| _ -> failwith "bad value type"
let someIndexes = [
getNewIndexForValueType 9;
getNewIndexForValueType false;
getNewIndexForValueType 5.67;
]
在我看來這是一個很直口(除F#版本我約束它只是值類型),但我得到的錯誤:
error FS0001: This expression was expected to have type AttributeIndexBase
but here has type AttributeIndex<int>
不會F#真的只是不支持的投孩子到C#的父母類型呢?
你有什麼打算與後來的「someIndexes」呢? – Brian 2010-08-20 16:10:23
要回答最後一個問題,請閱讀MSDN中的「Casting Object Types/Upcasting」:http://msdn.microsoft.com/en-us/library/dd233220.aspx – Jason 2010-08-20 20:29:56