【问题标题】:F# Error compilingF# 编译错误
【发布时间】:2015-05-07 19:05:32
【问题描述】:

我有以下导致编译错误的 F# 代码:

persistence.fs(32,21):错误 FS0072:根据此程序点之前的信息查找不确定类型的对象。在这个程序点之前可能需要一个类型注释来约束对象的类型。这可能会解决查找问题。

错误出现在“serializer.write....”这一行

任何帮助将不胜感激。

namespace persisitence
open System.Collections.Generic
open System
open System.IO

type LocalData<'T> =
    struct
        val mutable elements_ : 'T list
        val mutable lock_ : obj
        new(e: 'T list) = { elements_ = e ; lock_ = new obj() }
    end

type BinaryPersistenceOut<'T, ^W when ^W: (member write : ('T * BinaryWriter) -> unit)>(fn: string, serializer: ^W) as this = 
    let writer_ = new BinaryWriter(File.Open(fn, FileMode.Append))
    let mutable localdata_ = new LocalData<'T>([])
    let serializer_ = serializer
    let NUM_SECS_IN_MIN = 60
    let NUM_MSECS_IN_SEC = 1000
    let NUM_MIN_BETWEEN_COMMITS = 2
    let TIME_TO_WAIT = 15
    let closed_ = false

    let freq_ = NUM_MIN_BETWEEN_COMMITS * NUM_SECS_IN_MIN * NUM_MSECS_IN_SEC
    let path_ = fn
    let timer_ = new System.Timers.Timer((float) (NUM_MIN_BETWEEN_COMMITS * NUM_MSECS_IN_SEC) )

    let writetofile = 
        fun (arg: Timers.ElapsedEventArgs ) ->
            lock localdata_.lock_ ( fun () -> 
             if closed_ = false then
                for elem in localdata_.elements_ do
                    serializer.write(elem, writer_)
             )  

    do 
        timer_.Elapsed.Add(writetofile)

【问题讨论】:

    标签: f#


    【解决方案1】:

    虽然你可以像serializer.write(elem, writer_) 一样调用write 函数,但你不能。你必须像这样调用它:

    (^W: (member write : ('T * BinaryWriter) -> unit) (serializer, (elem, writer_)))
    

    完整代码块:

    type BinaryPersistenceOut<'T, ^W when ^W: (member write : ('T * BinaryWriter) -> unit)> (fn: string, serializer: ^W) as this = 
        let writer_ = new BinaryWriter(File.Open(fn, FileMode.Append))
        let mutable localdata_ = new LocalData<'T>([])
        let serializer_ = serializer
        let NUM_SECS_IN_MIN = 60
        let NUM_MSECS_IN_SEC = 1000
        let NUM_MIN_BETWEEN_COMMITS = 2
        let TIME_TO_WAIT = 15
        let closed_ = false
    
        let freq_ = NUM_MIN_BETWEEN_COMMITS * NUM_SECS_IN_MIN * NUM_MSECS_IN_SEC
        let path_ = fn
        let timer_ = new System.Timers.Timer((float) (NUM_MIN_BETWEEN_COMMITS * NUM_MSECS_IN_SEC) )
    
        let writetofile = 
            fun (arg: Timers.ElapsedEventArgs ) ->
                lock localdata_.lock_ ( fun () -> 
                 if closed_ = false then
                    for elem in localdata_.elements_ do
                        (^W: (member write : ('T * BinaryWriter) -> unit) (serializer, (elem, writer_)))
                 )  
    
        do 
            timer_.Elapsed.Add(writetofile)
    

    警告:这可以编译,但我不知道它是否符合您的要求。

    【讨论】:

    • type 行中的静态约束是否必要? writetofile 的表达式中的显式使用是否足以隐式应用它? (抱歉,在移动设备上。)
    • @ildjarn 我也想知道这一点,但如果我删除它以支持&lt;'T, ^W&gt;,编译器会抱怨。这就是 AFAICT,与您在内联函数中使用成员约束的方式不同。
    • @Mark:非常感谢。我实际上采取了传递函数而不是类型的方法。我可能会再次考虑这个,因为现在我知道如何调用该函数了。
    猜你喜欢
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 2010-09-29
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多