实例声明中的类型变量的顺序 [英] Order of type-variables in instance-declarations

查看:130
本文介绍了实例声明中的类型变量的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个 T a b 类型,并且我想写一个实例声明,例如一个 Functor 的实例声明,它的范围超过了 a not b'/ code>。这可能没有定义 newtype

Suppose I have a type T a b and I want to write an instance declarations e.g. an instance declaration for Functor that ranges over a and not b. Is this possible without defining a newtype?

我读什么是Haskell的多类型变量的顺序的规则?这导致我相信这是不可能的,但这对我来说似乎完全是任意的。

I read What is the rule of the order of multiple type variables in haskell? which leads me to believe that this is not possible, but this seems completely arbitrary to me.

我所希望的是这样的:

instance Functor (T * b)


推荐答案

这不是任意的。这就是Hindley-Milner类型推理如何处理更高级的类型和咖喱类型构造函数的应用。类型变量的统一是基于生成型构造函数的概念。也就是说,如果(fa)〜(gb),那么 f〜g a 〜b ,其中是类型相等。

It's not arbitrary. It's how Hindley-Milner type inference works with higher-kinded types and curried type constructor application. Unification of type variables is based on the concept of generative type constructors. That is, if (f a) ~ (g b), then f ~ g and a ~ b, where ~ is type equality.

让我们将其用于统一像(fmap f someT)这样的表达式,用于 someT :: T ab 。我将首先给出除 someT 新鲜类型变量之外的所有内容,以统一方式工作。

Let's apply that to unification of an expression like (fmap f someT), for someT :: T a b. I'll start by giving everything other than someT fresh type variables, to work the way unification does.

someT :: T a b
fmap :: (c -> d) -> f c -> f d
f :: e

由于 fmap 提供 f 作为第一个参数,我们统一(c - > d)〜e 。所以..

By the fact that fmap is provided f as a first argument, we unify (c -> d) ~ e. So..

fmap f :: f c -> f d
someT :: T a b

这就是生成它的地方。从这里,我们看到(f c)〜(T a b)。让我为清晰起见添加一些附加括号:(f c)〜((T a)b))。这就是类型构造函数在Haskell中的工作方式 - 它们与term级别的函数相同。通过发生性, f〜(T a) c〜b

This is where generativity comes into it. From here, we see (f c) ~ (T a b). Let me add some additional parenthesis for clarity: (f c) ~ ((T a) b). This is how type constructors work in Haskell - they are curried in the same way as term-level functions. By generativity, f ~ (T a) and c ~ b.

然后从那里:

Then from that:

fmap f someT :: T a d

因此, Functor 实例必须只对第二个类型的参数键入 T

So it's necessarily true that the Functor instance must operate only on the second type argument of the type T.

当然,这一切都可以追溯到类型推断算法。你可以放弃Hindley-Milner或curried类型的构造函数来使事情以不同的方式工作。但结果与Haskell完全不同,远远不止允许一些Haskell没有的实例。

Of course this all goes back to the type inference algorithm. You could give up Hindley-Milner or curried type constructors to make things work differently. But the result would be very different from Haskell in far more ways than just allowing a couple instances that Haskell doesn't.

这篇关于实例声明中的类型变量的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆