compiler-errors - F# 4.5.0.0 : Compilation errors: FS1198, FS0661 和 FS0001:我正在调整从 C# 到 F# 的接口(interface)

标签 compiler-errors functional-programming f# c#-to-f#

我的目标是将 FSharp.Core 版本 4.5.0.0 移植到 .NET 4.0。为了实现我的目标,我正在用 F# 重写 Theraot.Core 的部分内容,因为 FSharp.Core 不“接受”第三方库:https://github.com/theraot/Theraot/issues/121 .

我正在调整从 C# 到 F# 的接口(interface)。

C#中的接口(interface):
https://github.com/theraot/Theraot/blob/master/Framework.Core/System/Collections/Generic/IReadOnlyDictionary.cs

输入 F#:

namespace System.Collections.Generic

open Microsoft.FSharp.Core

type IReadOnlyCollection<'T> =
    inherit IEnumerable<'T>

    abstract Count : int with get

type IReadOnlyDictionary<'TKey, 'TValue> =
    inherit IReadOnlyCollection<KeyValuePair<'TKey, 'TValue>>

    abstract Keys : IEnumerable<'TKey> with get
    abstract Values : IEnumerable<'TValue> with get
    abstract Item : key : 'TKey -> 'TValue with get
    abstract ContainsKey : key : 'TKey -> bool
    abstract TryGetValue : key : 'TKey * [<System.Runtime.InteropServices.Out>] value : byref<'Value> -> bool

发生编译错误的地方:
https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/map.fs#L626
https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs#L88

在 C# 到 F# 时完美运行,但从 F# 到 F# 发生编译错误:

map .fs:

FS1198 在此程序点之前的非统一实例化中使用了通用成员“TryGetValue”。考虑重新排序成员,以便首先出现此成员。或者,显式指定成员的完整类型,包括参数类型、返回类型和任何其他泛型参数和约束。

FS0661 此绑定(bind)的一个或多个显式类或函数类型变量无法泛化,因为它们被限制为其他类型。

fslib-extra-pervasives.fs:

FS0001 这个表达式应该有类型
''一种'
但这里有类型
''T'

我也试过了,没有成功:
abstract TryGetValue : key : 'TKey * [<System.Runtime.InteropServices.Out>] value : 'Value -> bool

编辑:
我正在 F# 中迈出第一步。我发现的唯一信息是 F# 的不变性非常酷,但有时无法像 C# 那样编写 F#。

前两个编译器错误我不知道是从哪里来的,但是第三个是可以简化的:
namespace TestBugApplication1

open System.Collections.Generic

type DictImpl<'SafeKey,'Key,'T>(t : Dictionary<'SafeKey,'T>, makeSafeKey : 'Key->'SafeKey) =
    interface IReadOnlyDictionary<'Key, 'T> with
        member this.ContainsKey(key) = raise (System.NotImplementedException())
        member this.Count = raise (System.NotImplementedException())
        member this.GetEnumerator() = raise (System.NotImplementedException())
        member this.GetEnumerator() = raise (System.NotImplementedException())
        member this.Item
            with get (key) = raise (System.NotImplementedException())
        member this.Keys = raise (System.NotImplementedException())
        member this.TryGetValue(key, r) =
            match t.TryGetValue (makeSafeKey key) with
                            | false, _ -> false
                            | true, value ->
                                r <- value //<- Compiler error
                                true
        member this.Values = raise (System.NotImplementedException())

我还可以发送我正在编程的解决方案的下载链接。

最佳答案

您的问题不在于实现,而在于 IReadOnlyDictionary 的定义.

abstract TryGetValue : key : 'TKey * [<Out>] value : byref<'Value> -> bool

请注意,它是 'Value .这意味着 TryGetValue签名为 TryGetValue<V>(TKey key, out V value)而不是 TryGetValue(TKey key, out TValue value) .

将其更正为
abstract TryGetValue : key : 'TKey * [<Out>] value : byref<'TValue> -> bool

将使其编译。

额外的错误是推理错误。如果您正在实现重载成员,请对类型进行注释以避免歧义。
member this.GetEnumerator() : IEnumerator<KeyValuePair<'Key, 'T>> = 
    raise (System.NotImplementedException())

member this.GetEnumerator() : IEnumerator = 
    raise (System.NotImplementedException())

关于compiler-errors - F# 4.5.0.0 : Compilation errors: FS1198, FS0661 和 FS0001:我正在调整从 C# 到 F# 的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61275312/

相关文章:

java:用于不可变函数式数据结构的库

javascript - 无类型语言中是否存在模式匹配之类的东西

arrays - 为什么遍历数组比 Seq.find 更快

f# - 如何在前缀表示法中使用F#幂运算符(**)?

javascript - Vue 组件位于另一个组件中

haskell - 输入别名和 “instance … where”

java - "error: cannot find symbol HashMap"

c++ - 为什么 iostream 包含 time.h?

javascript - Ramda 函数在应用于参数时评估函数的相等性

function - 私有(private)函数与嵌套函数