在我与同事合作的项目中,我们使用了UrlParser模块,我们偶然发现了这个错误:
The type annotation for ourParser does not match its definition.
The type annotation is saying:
UrlParser.Parser a a
But I am inferring that the definition has this type:
UrlParser.Parser (String -> ?) (String -> ?)
Hint: A type annotation is too generic. You can probably just switch
to the type I inferred. These issues can be subtle though, so read
more about it.
Run Code Online (Sandbox Code Playgroud)
我们的代码是这样的
ourParser : UrlParser.Parser a a
ourParser =
UrlParser.oneOf
[ UrlParser.s "home"
, UrlParser.s "detail" </> UrlParser.string
]
Run Code Online (Sandbox Code Playgroud)
主要问题是:这个?符号是什么?它在哪里定义?如果我尝试在我的函数定义中复制/粘贴它,我会收到语法错误,好像Elm实际上不知道那个字符是什么...
以下问题是:我的代码如何发生这样的错误?
小智 6
您的备选列表中的第二个解析器组合在一起
UrlParser.s "detail" : Parser a a
UrlParser.string : Parser (String -> b) b
Run Code Online (Sandbox Code Playgroud)
运用
(</>) : Parser u v -> Parser v w -> Parser u w
Run Code Online (Sandbox Code Playgroud)
正如您所希望看到的,以下类型必须匹配:
u ~ a
v ~ a
v ~ (String -> b)
w ~ b
Run Code Online (Sandbox Code Playgroud)
结果类型是
UrlParser.s "detail" </> UrlParser.string : Parser (String -> b) b
Run Code Online (Sandbox Code Playgroud)
备选列表中的第一个解析器具有类型
UrlParser.s "home" : Parser c c
Run Code Online (Sandbox Code Playgroud)
因为您正在构建这些列表,所以它们必须具有相同的常规类型.因此c ~ (String -> b),但也c ~ b.你在这里有一个循环,导致无限类型.这就是无穷大符号的含义.
错误文本确实具有误导性,因为Elm的类型系统不支持无限类型(因为它们毫无意义).这听起来像一个错误,因为榆树应该解释无限类型总是指向编程错误.
该文档oneOf展示了如何通过使用来组合不同类型的解析器format.
无论如何,您需要将第一个解析器转换为类型的解析器Parser (String -> c) c.从类型来看,看起来应用于format "some string"第一个解析器已经足够了,但我不太了解Elm或UrlParser对此有任何保证.