ReasonML 签名不匹配
ReasonML Signature Mismatch
我在 ReasonML 中发现我定义的解析为 type mutationFunctionType = (~id: UUID.t, ~classroomId: UUID.t, unit) => unit;
的类型与我期望的 'a
之间的签名不匹配。 (见下文)。
[1] Signature mismatch:
[1] ...
[1] Values do not match:
[1] let callMutationWithApollo:
[1] ApolloMutation.apolloMutationType(Config.t) => mutationFunctionType
[1] is not included in
[1] let callMutationWithApollo:
[1] ApolloMutation.apolloMutationType(Config.t) => 'a
我很好奇为什么会收到此错误,因为我认为多态类型 `a 基本上可以被视为任何类型。
谢谢
类型多态性允许您以某些类型通用地编写函数。
例如,多态身份的类型为 'a => 'a
。
这意味着它可以通过实例化 'a
.
在类型 int => int
或 bool => bool
上使用
然而,这'a
并不意味着任何事情都会发生。它只在一个方向上起作用:
'a
可以变成任何东西,但任何东西都不能变成'a
。
所以从 ApolloMutation.apolloMutationType(Config.t) => 'a
你确实可以得到
ApolloMutation.apolloMutationType(Config.t) => mutationFunctionType
但你做的恰恰相反
例如,您不能将 int => int
函数转换为 int => 'a
函数。
顺便说一下,提供这样一个 int => 'a
或 ApolloMutation.apolloMutationType(Config.t) => 'a
类型的函数是不可能的,除非它 returns 错误或不终止。因此,我建议尽可能更新您的签名以明确提及 mutationFunctionType
.
I'm curious about why I'm receiving this error because I thought the polymorphic type `a could be treated as basically any type.
是的,你是对的,'a
意味着什么。但成为任何人究竟意味着什么?值的类型定义了可以在哪些上下文中使用该值。例如,如果您的值的类型为 int
,那么它可以用在任何需要 int
或 ''a
的地方。说你的函数有类型 'a
意味着你的函数可以用来代替 int
和 unit
或代替任何其他函数。实际上,“a”类型意味着可以使用此值代替任何其他值。
换句话说,你签名中的函数类型就是你的合约。并且您试图通过说您的功能可以适用于任何地方来过度约束自己。类型检查器说你不对——你的函数只适用于非常特定的上下文
ApolloMutation.apolloMutationType(Config.t) => mutationFunctionType
它甚至不是多态的(也就是说,你的函数不可能适合一种以上的类型 - 它是 单态的,即只有一种类型)。
然而,有一个特定的上下文,其中使用 'a
意味着 "I don't care, pick whatever type you want",这是当您指定 类型约束 时,即,当您在 let 绑定中注释函数的参数或变量时,例如,此处 'a
let sum = (x, y): 'a => x + y;
表示 "whatever type",尽管它是 int
,而且只是 int
。
当您提供注释(又名类型约束)时,类型检查器会将其添加为类型方程的附加约束,例如,
let pair: ('a, 'a) => ('a, 'a) = (x, y) => (x, y);
这里,函数pair
被限制为一对两个相等的(unifiable1)类型,但这些类型可以是任何类型,唯一重要的是他们是平等的。如果我们不添加这个约束,那么函数的类型将是 ('a,'b) => ('a,'b)
,这是更通用的。
1)其实并不要求它们相等,这样的约束只是说x
和y
必须统一,通常,在单态类型的情况下,这意味着它们应该相等,例如,int
只能与 int
统一,但在多态类型的情况下,尤其是子类型,将推断出最小上限,但这是一个完全不同的故事。
我在 ReasonML 中发现我定义的解析为 type mutationFunctionType = (~id: UUID.t, ~classroomId: UUID.t, unit) => unit;
的类型与我期望的 'a
之间的签名不匹配。 (见下文)。
[1] Signature mismatch:
[1] ...
[1] Values do not match:
[1] let callMutationWithApollo:
[1] ApolloMutation.apolloMutationType(Config.t) => mutationFunctionType
[1] is not included in
[1] let callMutationWithApollo:
[1] ApolloMutation.apolloMutationType(Config.t) => 'a
我很好奇为什么会收到此错误,因为我认为多态类型 `a 基本上可以被视为任何类型。
谢谢
类型多态性允许您以某些类型通用地编写函数。
例如,多态身份的类型为 'a => 'a
。
这意味着它可以通过实例化 'a
.
int => int
或 bool => bool
上使用
然而,这'a
并不意味着任何事情都会发生。它只在一个方向上起作用:
'a
可以变成任何东西,但任何东西都不能变成'a
。
所以从 ApolloMutation.apolloMutationType(Config.t) => 'a
你确实可以得到
ApolloMutation.apolloMutationType(Config.t) => mutationFunctionType
但你做的恰恰相反
例如,您不能将 int => int
函数转换为 int => 'a
函数。
顺便说一下,提供这样一个 int => 'a
或 ApolloMutation.apolloMutationType(Config.t) => 'a
类型的函数是不可能的,除非它 returns 错误或不终止。因此,我建议尽可能更新您的签名以明确提及 mutationFunctionType
.
I'm curious about why I'm receiving this error because I thought the polymorphic type `a could be treated as basically any type.
是的,你是对的,'a
意味着什么。但成为任何人究竟意味着什么?值的类型定义了可以在哪些上下文中使用该值。例如,如果您的值的类型为 int
,那么它可以用在任何需要 int
或 ''a
的地方。说你的函数有类型 'a
意味着你的函数可以用来代替 int
和 unit
或代替任何其他函数。实际上,“a”类型意味着可以使用此值代替任何其他值。
换句话说,你签名中的函数类型就是你的合约。并且您试图通过说您的功能可以适用于任何地方来过度约束自己。类型检查器说你不对——你的函数只适用于非常特定的上下文
ApolloMutation.apolloMutationType(Config.t) => mutationFunctionType
它甚至不是多态的(也就是说,你的函数不可能适合一种以上的类型 - 它是 单态的,即只有一种类型)。
然而,有一个特定的上下文,其中使用 'a
意味着 "I don't care, pick whatever type you want",这是当您指定 类型约束 时,即,当您在 let 绑定中注释函数的参数或变量时,例如,此处 'a
let sum = (x, y): 'a => x + y;
表示 "whatever type",尽管它是 int
,而且只是 int
。
当您提供注释(又名类型约束)时,类型检查器会将其添加为类型方程的附加约束,例如,
let pair: ('a, 'a) => ('a, 'a) = (x, y) => (x, y);
这里,函数pair
被限制为一对两个相等的(unifiable1)类型,但这些类型可以是任何类型,唯一重要的是他们是平等的。如果我们不添加这个约束,那么函数的类型将是 ('a,'b) => ('a,'b)
,这是更通用的。
1)其实并不要求它们相等,这样的约束只是说x
和y
必须统一,通常,在单态类型的情况下,这意味着它们应该相等,例如,int
只能与 int
统一,但在多态类型的情况下,尤其是子类型,将推断出最小上限,但这是一个完全不同的故事。