榆树的可比性意味着什么?

时间:2015-08-07 19:54:39

标签: elm

我无法理解榆树中comparable的确切含义。榆树似乎和我一样困惑。

在REPL上:

> f1 = (<)
<function> : comparable -> comparable -> Bool

所以f1接受可比较的内容。

> "a"
"a" : String
> f1 "a" "b"
True : Bool

所以似乎String具有可比性。

> f2 = (<) 1
<function> : comparable -> Bool

所以f2接受了可比较的内容。

> f2 "a"
As I infer the type of values flowing through your program, I see a conflict
between these two types:

    comparable

    String

因此String 不具有可比性?
为什么f2的类型不是number -> Boolf2可以接受哪些其他可比对象?

3 个答案:

答案 0 :(得分:6)

通常,当您在Elm中的类型中看到类型变量时,此变量不受约束。然后,当您提供特定类型的某些内容时,该变量将被该特定类型替换:

-- says you have a function:
foo : a -> a -> a -> Int
-- then once you give an value with an actual type to foo, all occurences of `a` are replaced by that type:
value : Float
foo value : Float -> Float -> Int

comparable是一个具有内置特殊含义的类型变量。这意味着它只能匹配&#34;可比较的&#34;类型,例如IntString和其他一些类型。但否则它应该表现相同。所以我觉得类型系统中有一个小错误,因为你得到:

> f2 "a"
As I infer the type of values flowing through your program, I see a conflict
between these two types:

    comparable

    String

如果错误不存在,你会得到:

> f2 "a"
As I infer the type of values flowing through your program, I see a conflict
between these two types:

    Int

    String

编辑:我为此错误打开了issue

答案 1 :(得分:3)

取自榆树文档: - here

  

可比类型包括numberscharactersstrings,   lists of comparable thingstuples of comparable things。注意   具有7个或更多元素的元组无法比较;为什么你的元组   那么大?

这意味着:

[(1,"string"), (2, "another string")]List (Int, String) - 具有可比性

但是

(1, "string", True)(Int, String, Bool)

[(1,True), (2, False)]List (Int, Bool ) - 无法比较

此问题已在here

中讨论

注意:当人们尝试在 中使用联合类型作为时,通常会遇到comparable类型的问题字典 即可。

联合类型的标签和构造器无法比较 所以以下内容甚至无法编译。

type SomeUnion = One | Two | Three
Dict.fromList [ (One, "one related"), (Two, "two related") ] : Dict SomeUnion String

通常当您尝试这样做时,您的数据结构会有更好的方法。但是在决定之前 - 可以使用AllDict

答案 2 :(得分:1)

我认为这个问题可能与this one有关。 IntString都是comparable,因为字符串可以与字符串进行比较,而int可以与int进行比较。可以采用任何两个可比对象的函数将具有签名comparable -> comparable -> ...,但在该函数的任何一个评估中,两个可比对象必须是相同类型。

我认为上面f2令人困惑的原因是1number而不是具体类型(这似乎阻止了编译器认识到可比较的必须是某种类型,可能应该是固定的)。如果你这样做:

i = 4 // 2
f1 = (<) i   -- type Int -> Bool
f2 = (<) "a" -- type String -> Bool

你会看到它实际上 comparable折叠到正确的类型。