将解决方案复制到其他位置时,F#Option会变得疯狂

时间:2012-06-26 01:37:29

标签: visual-studio-2010 f#

这非常奇怪,我希望有人会有一些见解来理解这一点。

我有一个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版本?我是不幸的不幸的僵硬者吗?

3 个答案:

答案 0 :(得分:2)

因此奇怪的症状也有同样奇怪的原因。

事实证明我引用的DLL之一(每个项目中无处不在的“Core”垃圾抽屉dll)必须有一些扩展方法,这些方法会导致编译器和visual studio使用的类型推断出现一些问题

当我删除open MyProject.Core并使用完全限定名称替换我正在使用的任何类型的引用时,奇怪的错误会神奇地消失。

所以,在这一点上,还有两个问题:

  1. 可能导致此问题的那种疯狂的扩展方法
  2. 为什么原始解决方案/项目不受此影响? (我猜这可能与引用传递给Fsc.exe调用的顺序有关......但我不确定)。
  3. 我实际上可能会深入挖掘,试图找出#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

后者摆脱了泛型参数的空约束。