我试图使用来自pipe3
库的FParsec
函数,但我不知道如何解决这个错误。
考虑到记录
type Point = { x: float; y: float }
和下面的解析器
let plistoffloats' =
pipe3 pfloat (pchar ',' .>> spaces) pfloat
(fun first z second -> { x = first; y = second })
我试图实现的是一个解析器,它接收格式为"1.1, 3.7"
的字符串并返回一个Point
。
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
示例也不起作用。
let parsesA = pchar 'a'
错误FS0030:值限制。值' parsesA‘被推断为具有泛型类型val parsesA:
Parser<char,'_a>
将参数显式地设置为'parsesA’,或者,如果您不希望它是泛型的,则添加一个类型注释。
发布于 2019-02-05 15:00:57
这是在FParsec文档中讨论的;它将发生在任何解析器中。原因是因为在.Net类型系统中,函数被允许是泛型的,但值不是--在FParsec中,您通常将解析器定义为值(例如,您通常在编写let psomething = ...
,其中psomething
不接受参数)。阅读链接文档页面,了解整个解释--我不会复制和粘贴整个内容--但简短的版本是,您可以做以下两件事中的一件:
test
函数,并确保它在解析器上的同一个源文件中使用:
让测试p=匹配运行p并成功地运行p( _,_) -> printfn "Success:%A“这听起来像是在尝试执行#1,但是除非在同一个源文件中用test plistoffloats'
调用解析器,否则F#类型推断将无法推断您的用户状态类型,并会给出错误。
您可以在这里阅读有关F#值限制错误的更多信息:理解F#值限制错误
_
位于Parser<_, UserState>
的第一个位置并不意味着“这种类型可以是任何东西”,就像_
在其他上下文中的意思一样,比如模式匹配。相反,类型注释中的_
意味着“请为我推断此类型,这样我就不必显式地指定它”。在FParsec上下文中,这非常有用,因为所有解析器都将UserState
作为它们的第二种类型参数,但是对于第一种类型的参数将有不同的类型。由于第一个类型参数是类型推断可以推断的参数,这意味着您可以将类型Parser<_, UserState>
复制并粘贴到所有解析器中,F#将在每种情况下执行正确的™操作。
https://stackoverflow.com/questions/54536779
复制相似问题