在F#中使用泛型和转换的问题

时间:2014-01-14 21:09:52

标签: .net generics casting f# type-conversion

使用以下列方式实施的基因组类型

type Genome<'T> (listIn : List<'T>)=
    member this.list = listIn
    member this.GetValues() =
        this.list

我在编写另一个代码片段时遇到了问题。

type IMutation =
    abstract member MutateMethod: Genome<'T> -> Genome<'T>

type DoubleGenomeMutation() = 
    member this.Mutate = (this :> IMutation).MutateMethod
    interface IMutation with
        member this.MutateMethod(genome: Genome<'T>) = 
            let randomIndex = MyRandom.Next(0, genome.list.Length)
            printfn "%d" randomIndex
            let newValue = MyRandom.NextDouble(Parameters.LowerBounds.Item(randomIndex), Parameters.UpperBounds.Item(randomIndex))

            let (newGenomeList : List<'double>, _) = 
                List.foldBack (fun elem acc -> 
                match acc with
                | (l, 0) -> (newValue::l, -1)
                | (l, i) -> (elem::l, i-1)) (genome.GetValues()) ([], genome.GetValues().Length - randomIndex - 1)

            new Genome<'T>(newGenomeList)

我发现在这里无法正确使用泛型机制。引用的样本效果

Error   2   Type mismatch. Expecting a
    float list    
but given a
    List<'a>    
The type 'float' does not match the type ''a'

在行

| (l, i) -> (elem::l, i-1)) (genome.GetValues()) ([], genome.GetValues().Length - randomIndex - 1)

在类似情况下,将变量向上或向下转换为解决方案 - 遗憾的是我无法以这种方式修复程序。我将非常感谢任何直接帮助以及有关所有问题根源的任何建议。

1 个答案:

答案 0 :(得分:2)

我没有MyRandom的来源,但如果我将MyRandom.Next替换为int,看起来应该如此,并将MyRandom.Double替换为{ {1}},然后我可以重现您的错误。

问题是double的返回类型不恰当地限制了其余的代码; MyRandom.NextDouble被声明能够接受任何类型的参数,但是然后您使用MutateMethod作为newValue案例中返回列表的一部分,这限制了另一种情况的类型。

您可能还收到来自(l, 0)的警告,指出它将您的newValue类型变量限制为'double类型,这是另一条线索。实际上float应该是'double,因为这是参数最初声明的方式。

如果我将'T的调用替换为抛出异常(可以有任何结果类型),则错误消失,这证实了这一诊断:

MyRandom.NextDouble