这非常奇怪,我希望有人会有一些见解来理解这一点。
我有一个F#2.0(Visual Studio 2010,目标.Net 4.0)解决方案,它在我最初创建它的位置正常工作,但是如果我尝试将其复制到新文件夹(因为我想要检查它)来源控制),我在构建时遇到了一些非常奇怪的错误。它们往往是:
error FS0803: Invalid use of a type name and/or object constructor. If necessary use 'new' and apply the constructor to its arguments, e.g. 'new Type(args)'. Overloads are: None() : unit.
或
error FS0001: This expression was expected to have type obj option but here has type Some<'a>
对于选项类型的使用,这些错误仅 ,这是一个这样的用法的简单示例:
let asOption e =
match e with
| null -> None
| _ -> Some(e)
现在,请记住,这是一个在原始位置编译得很好的解决方案。我已经尝试过像Clean / Rebuild那样的明显,删除obj和bin目录,重新启动Visual Studion,但仍然是这样。
两种情况下的引用DLL都是相同的,GAC的DLL是从GAC引用的,非GAC的dll是复制的,并且是从相同的相对路径引用的。只是为了好玩,我甚至将调用的输出窗口文本与用于编译每个解决方案的Fsc.exe相比较,以确保在两种情况下都使用相同的参数调用编译器,当然,它是。
任何人都知道可能导致这种情况的原因是什么?我是不是以某种方式从GAC中获得了一些奇怪的FSharp.Core.dll版本?我是不幸的不幸的僵硬者吗?
答案 0 :(得分:2)
因此奇怪的症状也有同样奇怪的原因。
事实证明我引用的DLL之一(每个项目中无处不在的“Core”垃圾抽屉dll)必须有一些扩展方法,这些方法会导致编译器和visual studio使用的类型推断出现一些问题
当我删除open MyProject.Core
并使用完全限定名称替换我正在使用的任何类型的引用时,奇怪的错误会神奇地消失。
所以,在这一点上,还有两个问题:
我实际上可能会深入挖掘,试图找出#1的答案。我不确定它是否暴露了F#编译器的某些错误(可疑),或者我的同事只是做了一些不自然的扩展方法(极有可能)
<强>更新强>:
看起来有人有一些F#envy并在Core项目中创建了一个Option<T>
类。几乎可以解释事情。我没有尝试过看看Fsc.exe调用中包含的顺序是否有所不同,但我有一种感觉就是它。
答案 1 :(得分:0)
参考文献几乎不应来自GAC,它们应来自Reference Assemblies
。发布您正在目击的fsc.exe命令行,也许它会更多的亮点。我猜测FSharp.Core引用以某种方式搞砸了(可能与它的引用程序集旁边的sigdata / optdata文件有关?)
(指出一个非常奇怪的症状!)
答案 2 :(得分:0)
假设F#编译器是确定性的,显然必须在调用方式方面有所不同,可能在环境变量中。您是否尝试过从命令行运行MSBuild?它通常有助于这些事情。
对于发生了什么的猜测是F#为您的代码推断出不同的类型。您是否尝试过限制它只需要处理简单类型?例如:
let asOption (e: obj) =
match e with
| null -> None
| _ -> Some(e)
否则:
let asOption<'T> (x: 'T) : option<'T> =
if x :> obj = null then None else Some x
后者摆脱了泛型参数的空约束。