- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将一些 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
一切都很顺利,直到我开始使用“未采用基因”方法。下面是该方法的 C# 代码(我还需要返回默认类型的帮助,但还没有做到这一点):
private GENE_TYPE GetNotTaken(Chromosome<GENE_TYPE> source,
IList<GENE_TYPE> taken)
{
int geneLength = source.Size;
for (int i = 0; i < geneLength; i++)
{
GENE_TYPE trial = source.GetGene(i);
if (!taken.Contains(trial))
{
taken.Add(trial);
return trial;
}
}
return default(GENE_TYPE);
}
我看到的编译器错误包括:
"The generic member 'GeneNotTaken' has been used at a non-uniform instantiation prior to this program point. Consider reordering the members so this member occurs first. Alternatively, specify the full type of the member explicitly, including argument types, return type and any additional generic parameters and constraints."
和
"This code is less generic than required by its annotations because the explicit type variable 'GeneType' could not be generalized. It was constrained to be 'unit'."
您可能会认为第一个错误是非常清楚的,除非您可以看到我在此之前没有使用 GeneNotTaken 成员,这就是为什么我不知道问题是什么。
我的问题的第二部分是如何在方法末尾添加 return default('GeneType) 。
如果您对改进我的代码还有其他建议,请随时分享。
最佳答案
出现错误消息的原因是您执行 GeneTaken
实际上并没有返回 trial
值(value)。问题是 F# 没有命令式 return
陈述。
在 F# 中,if .. then ..
被视为计算并给出一些结果的表达式。例如,您可以写 let a = if test then 10 else 12
。当您省略 else 分支时,语句的主体必须是返回 unit
的命令式操作。 (表示无返回值的类型)。你不能写let a = if test then 42
- 如果test = false
,结果的值是多少?
您可以通过使用递归循环编写方法来修复它 - 然后您就有一个实际上返回 trial
的方法。因此 F# 类型检查器不会感到困惑:
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
使用 Seq.tryPick
的替代(可能更好)实现功能:
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
为了给出一些一般提示,我可能不会使用 Unchecked.defaultof<'GeneType>
相反,您应该使用 option
当您处理可能缺少值的情况时键入。结果类型GeneNotTaken
那么将是option<'GeneType>
。而不是match
你可以写:
trial |> Option.map (fun actualTrial ->
taken.Add(actualTrial)
actualTrial )
此外,您的代码使用了大量突变,这在 F# 中编写函数代码时可能不是最好的做法。但是,如果您刚刚学习 F#,那么最好先将一些 C# 代码重写为 F#。随着您了解更多,您应该寻找避免突变的方法,因为这将使您的 F# 代码更加惯用(并且编写它也会更有趣!)
关于generics - F# 泛型类型问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5286119/
generic parameters of trait function 的简单示例: trait Ext: Sized { fn then(self, f: fn(Self) -> R) -
在下面的代码中,为什么 Groovy 似乎忽略了方法 barMany 中提供的闭包参数的泛型类型声明: import groovy.transform.CompileStatic @CompileSt
据我所知,Prolog 没有任何内置机制用于generic programming。 .可以使用统一来模拟泛型,但这需要在运行时进行类型检查: :- initialization(main). :-
在我的应用程序中,我有一个 Board。董事会由细胞组成。每个单元格都有一个 int 值。有几种类型的 Board 可以扩展 Board。每种类型的板将以不同方式表示单元格。例如,一个人会使用 Lis
我想将存储的属性添加到 UIView 子类中,例如UIView、UIImageView、UIPickerView等, 我只需要从子类创建 UIView 的实例子类仅类型不同,所有属性和方法都相同。 T
这个问题在这里已经有了答案: Any type and implementing generic list in go programming language (2 个答案) 关闭 6 个月前。
我有以下代码as seen in ideone.com : import java.util.*; class Test{ interface Visitor{ public
在 Swift 中,我们可以对序列等通用项编写扩展: extension Sequence where Iterator.Element : ObservableType { } 这将保证扩展仅适用于
我知道这听起来很困惑,但这是我能解释的最好的了。 (您可以建议一个更好的标题)。我有 3 节课:- A public class A > { ... } B public class B {
我目前在大学攻读 CS,我刚刚开始学习数据结构和算法类(class)。我的教授非常喜欢(实际上是强制我们)使用 Ada。为了取得成功,我开始查找一些东西并找到了这段代码,它描述了如何编写通用堆栈: g
我正在玩 Scala By Example 开头的 QuickSort 示例并尝试将其调整为通用类型 A ,而不仅仅是 Int s。 到目前为止我的工作是 def sort[A new Y(i, -
谁能解释为什么下面的第二个例子不能编译? “测试 2”给出“错误 FS0670:此代码不够通用。类型变量 ^a 无法泛化,因为它会超出其范围。”。我无法理解此错误消息。 // Test 1 type
如何将泛型存储在非泛型对象持有的泛型TList中? type TXmlBuilder = class type TXmlAttribute= class Name: Str
我正在尝试通过遵循 wiki article 创建如何使用 GHC.Generics 的最小工作示例.这是我所拥有的: {-# LANGUAGE DefaultSignatures, DeriveGe
我正在尝试将 get 函数添加到 wiki 中描述的通用序列化中。 。有些部分看起来很简单,但有一些地方我非常不确定要写什么,毫不奇怪,我遇到了编译错误。我已经查看了原始论文以及 cereal 中的实
为什么这段代码有效? $v):void { print_r($v); } test(Vector {1, array("I'm an array"), 3}); 它不应该抛出错误吗?什么是应
有没有办法让 Rust Generic 只接受原始类型?我想稍后迭代值中的位,并且我知道这只有在原始类型中才有可能。 struct MyStruct { my_property: T // m
假设我有一个简单的类 public class MyObject { } 以及处理MyObject子类的handler接口(interface) public interface MyObjectHa
出于某种原因,我正在努力通过使用通用基类来实现通用接口(interface)的属性,如下所示: public interface IParent where TChild : IChild {
我收到以下错误。 google了一天多,还是找不到具体的解决方法,求大神指点,谢谢 ERROR: Cannot implicitly convert type System.Collections.G
我是一名优秀的程序员,十分优秀!