Generics 泛型类型的F#问题

Generics 泛型类型的F#问题,generics,f#,types,annotations,c#-to-f#,Generics,F#,Types,Annotations,C# To F#,我试图将一些C代码转换为F代码,但遇到了一个小问题。以下是我已经掌握的F#代码: open System open System.Collections open System.Collections.Generic type Chromosome<'GeneType>() = let mutable cost = 0 let mutable (genes : 'GeneType[]) = Array.zeroCreate<'GeneType> 0

我试图将一些C代码转换为F代码,但遇到了一个小问题。以下是我已经掌握的F#代码:

open System
open System.Collections
open System.Collections.Generic

type Chromosome<'GeneType>() =
    let mutable cost = 0
    let mutable (genes : 'GeneType[]) = Array.zeroCreate<'GeneType> 0
    let mutable (geneticAlgorithm : GeneticAlgorithm<'GeneType>) = new GeneticAlgorithm<'GeneType>()

    /// The genetic algorithm that this chromosome belongs to.
    member this.GA
        with get() = geneticAlgorithm
        and set(value) = geneticAlgorithm <- value

    /// The genes for this chromosome.
    member this.Genes
        with get() = genes
        and set(value) = genes <- value

    /// The cost for this chromosome.
    member this.Cost
        with get() = cost
        and set(value) = cost <- value

    /// Get the size of the gene array.
    member this.Size = genes.Length

    /// Get the specified gene.
    member this.GetGene(gene:int) =
        genes.[gene]

    member this.GeneNotTaken(source:Chromosome<'GeneType>, taken:IList<'GeneType>) =
        let geneLength = source.Size
        for i in 0 .. geneLength do
            let trial = source.GetGene(i)
            if(not (taken.Contains(trial))) then
                taken.Add(trial)
                trial
开放系统
开放系统。集合
open System.Collections.Generic

类型染色体)=new GeneticAlgorithm,take:IList产生错误消息的原因是
GeneTake
的实现实际上没有返回
trial
值。问题是F#没有命令式
return
语句

在F#中,
if。。然后..
被视为一个表达式,该表达式求值并给出一些结果。例如,您可以编写
让a=if测试然后10 else 12
。省略else分支时,语句体必须是返回
unit
(表示无返回值的类型)的命令式操作。您不能编写
让a=if-test然后42
-如果
test=false
,结果的值是多少

您可以通过使用递归循环编写方法来修复它,然后您就有了一个实际返回
trial
的方法,因此F#type checker不会被混淆:

member this.GeneNotTaken
    (source:Chromosome<'GeneType>, taken:IList<'GeneType>) : 'GeneType =
  let geneLength = source.Size
  let rec loop i =
    if i >= geneLength then Unchecked.defaultof<'GeneType> // Return default
    let trial = source.GetGene(i)
    if (not (taken.Contains(trial))) then
      // Gene was found, process it & return it
      taken.Add(trial)
      trial
    else 
      // Continue looping
      loop (i + 1)
  loop 0

为了给出一些一般性的提示,我可能不会使用
Unchecked.defaultof我想你会注意到输入错误,但我认为最后一个循环0在答案的第一部分越位了
member this.GeneNotTaken
    (source:Chromosome<'GeneType>, taken:IList<'GeneType>) : 'GeneType =
  let geneLength = source.Size
  let rec loop i =
    if i >= geneLength then Unchecked.defaultof<'GeneType> // Return default
    let trial = source.GetGene(i)
    if (not (taken.Contains(trial))) then
      // Gene was found, process it & return it
      taken.Add(trial)
      trial
    else 
      // Continue looping
      loop (i + 1)
  loop 0
member this.GeneNotTaken
    (source:Chromosome<'GeneType>, taken:IList<'GeneType>) : 'GeneType =
  let geneLength = source.Size
  // Find gene that matches the given condition
  // returns None if none exists or Some(trial) if it was found
  let trial = [ 0 .. geneLength - 1 ] |> Seq.tryPick (fun i ->
    let trial = source.GetGene(i)
    if (not (taken.Contains(trial))) then Some(trial) else None) 
  match trial with 
  | Some(trial) ->
      // Something was found
      taken.Add(trial)
      trial
  | _ -> 
      Unchecked.defaultof<'GeneType> // Return default
  trial |> Option.map (fun actualTrial ->
      taken.Add(actualTrial)
      actualTrial )