首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >FParsec和pipe3使参数显式或添加类型表示法。

FParsec和pipe3使参数显式或添加类型表示法。
EN

Stack Overflow用户
提问于 2019-02-05 14:37:47
回答 1查看 204关注 0票数 3

我试图使用来自pipe3库的FParsec函数,但我不知道如何解决这个错误。

考虑到记录

代码语言:javascript
运行
复制
type Point = { x: float; y: float }

和下面的解析器

代码语言:javascript
运行
复制
let plistoffloats' =
    pipe3 pfloat (pchar ',' .>> spaces) pfloat 
        (fun first z second -> { x = first; y = second })

我试图实现的是一个解析器,它接收格式为"1.1, 3.7"的字符串并返回一个Point

代码语言:javascript
运行
复制
run plistoffloats' "1.1, 3.7"

输入"1.1, 3.7"

期望输出Point = {x = 1.1; y = 3.7;}

错误

错误FS0030:值限制。“plistoffloats”的值被推断为具有泛型类型val:Parser <Point,'__a> 要么将参数设置为“plistoffloats”显式,要么,如果您不希望它是泛型的,则添加一个类型注释。

一个简单的pchar示例也不起作用。

代码语言:javascript
运行
复制
let parsesA = pchar 'a'

错误FS0030:值限制。值' parsesA‘被推断为具有泛型类型val parsesA:Parser<char,'_a>将参数显式地设置为'parsesA’,或者,如果您不希望它是泛型的,则添加一个类型注释。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-05 15:00:57

这是在FParsec文档中讨论的;它将发生在任何解析器中。原因是因为在.Net类型系统中,函数被允许是泛型的,但值不是--在FParsec中,您通常将解析器定义为值(例如,您通常在编写let psomething = ...,其中psomething不接受参数)。阅读链接文档页面,了解整个解释--我不会复制和粘贴整个内容--但简短的版本是,您可以做以下两件事中的一件:

  1. 创建如下所示的test函数,并确保它在解析器上的同一个源文件中使用: 让测试p=匹配运行p并成功地运行p( _,_) -> printfn "Success:%A“
  2. 使用类型注释对解析器进行注释,如下所示: 键入UserState = unit //您可能会更改这个稍后让plistoffloats‘:Parser<_,UserState> = //

这听起来像是在尝试执行#1,但是除非在同一个源文件中用test plistoffloats'调用解析器,否则F#类型推断将无法推断您的用户状态类型,并会给出错误。

您可以在这里阅读有关F#值限制错误的更多信息:理解F#值限制错误

_位于Parser<_, UserState>的第一个位置并不意味着“这种类型可以是任何东西”,就像_在其他上下文中的意思一样,比如模式匹配。相反,类型注释中的_意味着“请为我推断此类型,这样我就不必显式地指定它”。在FParsec上下文中,这非常有用,因为所有解析器都将UserState作为它们的第二种类型参数,但是对于第一种类型的参数将有不同的类型。由于第一个类型参数是类型推断可以推断的参数,这意味着您可以将类型Parser<_, UserState>复制并粘贴到所有解析器中,F#将在每种情况下执行正确的™操作。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54536779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档