榆树中的无穷大符号

mar*_*osh 4 elm

在我与同事合作的项目中,我们使用了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对此有任何保证.