什么是错误“类型实例化涉及 byref 类型。” F# 中的解决方法是什么

2024-05-09

我有一些代码包装 TA-Lib,很多包装器非常相似:

let sma (timePeriod: int) (data: float[]) =
    let mutable outStartIndex = 0
    let mutable outNbElement = 0

    let mutable smaData : float array = Array.zeroCreate (data.Length - timePeriod + 1)

    let retCode = Core.Sma(0, (data.Length - 1), data, timePeriod, &outStartIndex, &outNbElement, smaData)

    if retCode <> Core.RetCode.Success then
        invalidOp (sprintf "AssertRetCodeSuccess")

    let padding = Array.create (timePeriod - 1) System.Double.NaN
    Array.append padding smaData



let ema (timePeriod: int) (data: float[]) =
    let mutable outStartIndex = 0
    let mutable outNbElement = 0
    let mutable emaData : float array = Array.zeroCreate (data.Length - timePeriod + 1)

    let retCode = Core.Ema(0, (data.Length - 1), data, timePeriod, &outStartIndex, &outNbElement, emaData)

    if retCode <> Core.RetCode.Success then
        invalidOp (sprintf "AssertRetCodeSuccess")

    let padding = Array.create (timePeriod - 1) System.Double.NaN
    Array.append padding emaData

我想做的是创建一个通用函数,我可以在其中传递 TA-Lib 函数来调用。就像是:

let myGenericFunction (timePeriod: int) (data: float[]) TALibFunc =
    let mutable outStartIndex = 0
    let mutable outNbElement = 0

    let mutable smaData : float array = Array.zeroCreate (data.Length - timePeriod + 1)

    let retCode = TALibFunc(0, (data.Length - 1), data, timePeriod, &outStartIndex, &outNbElement, smaData)

    if retCode <> Core.RetCode.Success then
        invalidOp (sprintf "AssertRetCodeSuccess")

    let padding = Array.create (timePeriod - 1) System.Double.NaN
    Array.append padding smaData

但我得到的错误是:

[FS0412] 类型实例化涉及 byref 类型。 Common IL 规则不允许这样做。

有解决方法吗?我对这个问题不太熟悉。


简短回答:替换你的mutable参数与ref.


TA-Lib 有一个非常不幸的 API:那些讨厌的 APIout-参数(在 F# 中称为byref),他们总是惹麻烦。在这种情况下,它们不能是泛型类型实例化的一部分。

这是一个更短的例子。考虑一个好的旧list<T>。我们可以做一个空的list<int>:

let noInts = [] : list<int>

但如果那些怎么办ints are byref?

let noRefs = [] : list< byref<int> >

编译器说,无能为力。类型实例化涉及 byref 类型。 Common IL 规则不允许这样做。 Sorry.


在你的情况下,最后一个参数myGenericFunction是一个 F# 函数。在 F# 中,函数由类型表示FSharpFunc<T, R> (where T是论证并且R是结果)。所以你最后一个参数的类型是这样的:

FSharpFunc< int * int * float array * int * byref<int> * byref<int> * float array, int >

看到那两个byref<int>在里面吗?那些是&outStartIndex and &outNbElement。并且它们在通用实例化中是被禁止的。倒霉。


但还有希望!

The mutable关键字只是在 F# 中创建可变单元格的两种方法之一。另一种方法是ref:

let x = ref 0     // Initialization
printfn "%d" !x   // Prints "0"
x := 42           // Mutation
printfn "%d" !x   // Prints "42"

这是一个老派的事情,早于mutable,作为库实现(而不是语言构造),并且在大多数情况下mutable更好。但这不是其中之一!

事实证明:

  1. 与真正的 .NET CIL 不同out-参数,ref单元格可以成为通用实例化的一部分就好了。因为,从 .NET 的角度来看,它们没有什么特别的——只是另一个类。
  2. F# 编译器对它们有特殊的用途:当预期类型是ref,但是你试图传递一个带有out- 参数代替它,编译器将自动为您生成一些包装代码。

因此,有了这些知识,您就可以修改myGenericFunction像这样:

let myGenericFunction (timePeriod: int) (data: float[]) TALibFunc =
    let outStartIndex = ref 0
    let outNbElement = ref 0

    let mutable smaData : float array = Array.zeroCreate (data.Length - timePeriod + 1)

    let retCode = TALibFunc(0, (data.Length - 1), data, timePeriod, outStartIndex, outNbElement, smaData)

    ...

然后消费者可以这样称呼它:

myGenericFunction 42 [|1; 2; 3|] Core.Sma // Wrapping code gets generated here
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么是错误“类型实例化涉及 byref 类型。” F# 中的解决方法是什么 的相关文章

  • 如何搭建Windows Phone开发环境并使用F#开发应用程序?

    我已经下载了Windows Phone开发工具 但我不知道如何使用F 来开发应用程序 目前是C 将 F 和 Windows Phone 模板安装到 Visual Studio 中可以让生活变得更轻松 如果您打开 Visual Studio
  • F# 中序列的递归函数

    这是一个相当微不足道的问题 但快速的谷歌搜索并没有给我答案 为序列编写递归函数的标准方法是什么 对于列表 您可以使用空列表和头 尾模式进行模式匹配 序列的等效项是什么 没有标准的方法可以做到这一点 因为您很少为序列编写递归函数 您应该查看各
  • 是 F# 映射上的迭代还是集合中序遍历?

    AFAIK F Map 和 set 被实现为红黑树 所以我猜这些的迭代将是有序遍历 我做了一些测试 迭代结果总是排序的 但我想确定一下 是按顺序遍历吗 MSDN 上的文档非常适合解决这个问题 例如 返回值Set toSeq http msd
  • 何时在 F# 中使用区分联合与记录类型

    在继续讨论复杂的示例之前 我试图先弄清楚 F 的基础知识 我正在学习的材料介绍了区分联合和记录类型 我已经审阅了两者的材料 但我仍然不清楚为什么我们要使用其中之一而不是另一个 我创建的大多数玩具示例似乎都可以在两者中实现 记录似乎非常接近我
  • 在 IEnumerable 上使用 Seq 函数 [重复]

    这个问题在这里已经有答案了 我正在尝试在 IEnumerable 上应用 Seq 函数 更具体地说 它是System Windows Forms HtmlElementCollection它实现了ICollection and IEnume
  • F# 中类型约束的顺序

    这适用于 F 4 0 type Something lt a b when b gt seq lt b gt gt 这不会 type Something lt b when b gt seq lt b gt a gt 类型名称中出现意外的符
  • f# 运行总计序列

    好吧 这看起来应该很容易 但我就是不明白 如果我有一个数字序列 如何生成由运行总计组成的新序列 例如 对于序列 1 2 3 4 我想将其映射到 1 3 6 10 以适当的功能方式 Use List scan https msdn micro
  • F# 类型提供程序与 Lisp 宏

    我一直在阅读有关 F 3 0 类型提供程序的内容 例如here http msdn microsoft com en us library hh156509 aspx 并且它们似乎基于一种编译时代码生成 在这方面我想知道它们与 Lisp 宏
  • F# 正确使用序列缓存

    我正在尝试将 Seq cache 与我制作的函数一起使用 该函数返回最多为 N 的素数序列 不包括数字 1 我无法弄清楚如何将缓存的序列保留在范围内 但仍然使用它在我的定义中 let rec primesNot1 n 2 n gt Seq
  • 将 C# 代码转换为 F#(if 语句)

    我想知道如何转换此代码逐行从 C 到 F 我不想使用任何类型的 F 习惯用法或类似的东西 我想了解如何直接映射C 的构造到 F 这是 C 代码 requires l Length gt 0 int GetMinimumValue List
  • F# 和模糊逻辑

    我知道这可能听起来很奇怪 但我想知道 Microsoft Visual F 正在进入的这个新世界中的一件事 这种语言有很多应用 我要学习 关于解析 函数式编程 结构化编程 但是人工智能呢 模糊逻辑有什么应用吗 F 是一种适合模糊逻辑应用程序
  • Async.StartChild是否存在内存泄漏?

    当我运行以下测试 使用 F 2 0 构建 时 我得到 OutOfMemoryException 在我的系统上大约需要 5 分钟才能达到异常 如果它作为 x86 进程运行 则为 i7 920 6gb ram 但无论如何我们都可以在任务管理器中
  • 在 Deedle 系列中算得上独一无二

    我想对我的数据框中的系列有一个概述 例如 pandas 的唯一值计数 我不知道是否有内置函数可以实现这一点 到目前为止 我已经完成了一个函数来获取不同特征的数量 我可以设法完成这项工作 我的问题只是关于内置功能 let unique s D
  • F# 检查列表是否为空

    作为 F 新手 我正在尝试实现一个简单的函数 该函数将索引和列表作为参数 然后返回给定索引的列表值 let rec getElementAtIndex index int list a list match index list with
  • F# 命名约定

    F 是否有 官方 命名 大小写约定 我总是怀疑是否使用 C 风格 Class MyFunctionName or Module my function name 在 F 中 您应该混合 BCL 类和 F 库类 它们具有不同的大小写 并且代码
  • 如何使用 .Net Core 和 VSCode 在调试模式下执行测试?

    如何使用 Net Core 和 VSCode 在调试模式下执行测试 我当前正在命令行上运行以下命令 dotnet Test 但是 这不是在调试模式下执行测试 我要附加调试器吗 如果是这样 怎么办 如有必要 请将测试项目转换为控制台应用程序
  • F# 尝试处理未处理的异常

    在下面的代码中 我想读取一个文件并返回所有行 如果存在 IO 错误 我希望程序退出并将错误消息打印到控制台 但程序仍然遇到未处理的异常 对此的最佳实践是什么 我想我不需要Some None因为无论如何我都希望程序在错误时退出 谢谢 let
  • 您可以使用 .net core 运行 F# 脚本文件 (.fsx) 吗?

    是否可以使用 net core 运行 fsx 文件 相当于fsharpi在单声道上 它在 NETCore v3 0 或更高版本中开箱即用 cat hello fsx usr bin env fsharpi printfn hello wor
  • F# 使用 while 循环

    我有一个数据读取器 我想从中返回行集合 在阅读了一天的书籍后 我无法找到在 f 中执行此操作的最佳方法 我可以在 F 中以正常的 C 方式进行操作 但这不是我使用 f 的原因 这就是我想要实现的目标 let values while rea
  • 从静态成员访问 let 绑定字段

    有没有办法从静态成员访问 let 绑定字段 下面给出了指示的错误 type Foo x let x x static member test let foo Foo System DateTime Now Month printfn A f

随机推荐