Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 使用Span<;T>;在F中:为什么这不好?_F# - Fatal编程技术网

F# 使用Span<;T>;在F中:为什么这不好?

F# 使用Span<;T>;在F中:为什么这不好?,f#,F#,我正在尝试使用Span实现一个二进制解析器组合器库。我不确定这是否真的是个好主意,我只是想更多地了解两者 不久前,我已经编写了一个小型二进制解析器,使用它可以完美地工作 代码如下所示: type ByteRange= {字节:字节数组 BeginIndex:int EndIndex:int} 类型parserror Result>) 让succeed value=Parser Ok(值,字节) let fail error=解析器错误 让内部结果= 分析器 匹配结果 |确定值->确定(值,字节)

我正在尝试使用Span实现一个二进制解析器组合器库。我不确定这是否真的是个好主意,我只是想更多地了解两者

不久前,我已经编写了一个小型二进制解析器,使用它可以完美地工作

代码如下所示:

type ByteRange=
{字节:字节数组
BeginIndex:int
EndIndex:int}
类型parserror Result>)
让succeed value=Parser Ok(值,字节)
let fail error=解析器错误
让内部结果=
分析器
匹配结果
|确定值->确定(值,字节)
|错误->错误(格式错误)
让内部映射f(解析器解析)=
分析器
将parse byteRange与
|正常(值',状态')->正常(f值',状态')
|错误->错误错误
...
我试着用Span而不是ByteRange来实现它,但我就是做不到

以下是我尝试过的:

模块二进制解析器
开放系统
open System.Runtime.CompilerServices
类型分析器错误
类型分析器=
Span->parsingreult>
让我们成功(价值观:a)=
乐趣(字节:Span)->
成功{Value=Value;Bytes=Bytes}
失败错误=
乐趣->
故障错误
让内部结果=
趣味字节->
匹配结果
|确定值->成功{value=value;Bytes=Bytes}
|错误->失败(FormatError错误)
让内部映射f(解析:解析器)=
趣味字节->
将解析字节与
|成功{Value=Value';Bytes=Bytes'}->Success{Value=f Value';Bytes=Bytes'}
|故障错误->故障错误
我在
匹配解析器字节与
行中的
映射
函数中发现以下错误: 错误FS0418:此时无法使用byref类型的值“bytes”

这是什么意思?为什么我不能在这里使用Span?有人尝试过用Span实现解析器组合器吗?你会如何解决这个问题

提前感谢。

不支持此模式(
Span
或其他类似于byref的结构作为高阶函数参数):

let internal map f (parse: Parser<_, _>) =
    fun bytes ->
        match parse bytes with
        | Success { Value = value'; Bytes = bytes' } -> Success { Value = f value'; Bytes = bytes' }
        | Failure error -> Failure error
let内部映射f(parse:Parser)=
趣味字节->
将解析字节与
|成功{Value=Value';Bytes=Bytes'}->Success{Value=f Value';Bytes=Bytes'}
|故障错误->故障错误
更简单的形式:

let foo (f: Span<int> -> int) (x: Span<int>) = f x
让foo(f:Span->int)(x:Span)=fx 在
f
上也给出了一个错误。
byref
有一些细微的怪癖,比如类型和类型缩写隐藏了
parse
上的错误,但是如果你给它一个明确的签名,你就会看到它

原因是类
byref
的结构只在堆栈上分配。但是,F#中的高阶函数使用堆分配。这将是一个矛盾,所以它不被支持