【问题标题】:Why is F# inferring my function implements IComparable?为什么 F# 推断我的函数实现了 IComparable?
【发布时间】:2012-04-29 03:37:42
【问题描述】:

我是一名业余程序员(职业厨师),目前正在尝试自学 F# 和一般的函数式编程。

反正我是在胡闹DeflateStream,写了下面两个函数:

let Compress compressMe =
    let ds = new DeflateStream(File.Create("compressed.txt"), CompressionMode.Compress)
    File.OpenRead(compressMe).CopyTo(ds)
    ds.Close()

let Decompress =
    let ds = new DeflateStream(File.OpenRead("compressed.txt"), CompressionMode.Decompress)
    ds.CopyTo(File.Create("decompressed.txt"))
    ds.Close()

在 main 函数的主体中,它们被一个接一个地调用,如下所示:

Compress args.[0]
Decompress

但是,如果在程序运行时compressed.txt 不存在Decompress 会引发FileNotFoundException,这令人惊讶,因为唯一可能引发此问题的是对File.OpenRead("compress.txt") 的调用。大约一个小时后,我发现 Decompress 正在实现 IComparable 并在主函数中调用它之前被执行。我发现通过将其定义更改为 let Decompress () = [...] 它不再实现 IComparable 并且我的代码按预期执行。谁能告诉我为什么 F# 推断IComparable 以及为什么这样的推断会导致函数在标有[<EntryPoint>] 的主函数之前执行?另外,请原谅我代码的命令风格,我对此非常陌生。

提前致谢。

【问题讨论】:

  • 顺便说一下,DeflateStream 实现了 IDisposable,所以你应该使用“use”关键字而不是“let”来创建它。这将确保在流超出范围时正确处理(并关闭)流。见msdn.microsoft.com/en-us/library/dd233240(v=vs.110).aspx
  • 谢谢,我会记住的。
  • 它推断 IComparable 似乎很奇怪,因为据我所知,表达式的类型是单位(ds.Close i 单位的返回类型)

标签: f# type-inference


【解决方案1】:

我不完全确定 IComparable 位,但您遇到的问题是,如果没有括号,编译器会将 Decompress 视为 value 而不是 function时间>。这与你写的情况类似。

let compressedName = "compressed.txt"

在这种情况下,compressedName 现在是一个值。添加括号告诉编译器这是一个函数,每次调用该函数时都必须调用其代码,而不是由您编写的代码初始化一次(在入口点之前)的值。

【讨论】:

  • 谢谢。我认为这很简单。
【解决方案2】:

当你写类似的东西时

let value = 
    //some long calculation
[<Entrypoint>]
let main args = ...

编译器在main 之前执行长计算。这是因为您稍后可能会在代码中使用该值。如您所见,要抑制这种情况,您需要使用let value() = ...

我不确定Icomparable 来自哪里,但这是发生什么事的关键。

注意,如果你写

let a = ...
let b = ...

编译器将保证ab 执行之前计算。

【讨论】:

    【解决方案3】:

    正如其他人所指出的,声明中没有括号很重要。

    let Decompres = ...
    

    声明unit 类型的变量。此类型用于表示“数据”(即使此数据未编码太多信息),并且它像任何其他面向数据的类型一样实现 IComparable。

    let Decompress() = ...
    

    声明一个函数,而 F# 中的函数不可比较,可能是因为没有普遍接受的函数相等概念。

    我看不出Decompress 的“IComparable-ness”与您遇到的异常有任何关系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 2011-11-23
      • 2018-07-23
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多