GHCi如何为类型变量选择名称? [英] How does GHCi pick names for type variables?

查看:130
本文介绍了GHCi如何为类型变量选择名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用交互式GHC解释器时,可以要求推断出的表达式类型:

  Prelude> :t map 
map ::(a - > b) - > [a] - > [b]

从<$ c开始,它似乎取自签名中的类型变量的名称$ c> map 是定义为

  map ::(a  - > b) - > [a]  - > [b] 
map _ [] = []
map f(x:xs)= fx:map f xs

$前奏曲中的b
$ b

。这很有道理!我的问题是:如果没有给定签名,如何挑选类型变量名称?



一个例子是

 前奏> :t map fst 
map fst :: [(b,b1)] - > [b]

选择名称 b b1 。很显然,必须进行重命名,但只需从 a b ,...开始



  map fst :: [(a,b)]  - > [a] 

取而代之的是,我发现它更具可读性。
<据我所知, ghci 按照与推断类型相同的顺序选择名称。它使用命名方案来决定结果的类型名称,它是 [b] ,因为这是<$ c $定义中指定的类型名称C>地图。然后它决定作为 map 的第一个参数的函数也应该返回类型为 b 的东西。



因此,要命名的其余类型变量是参数元组中第二个元素的类型变量,它是 fst ,并且再次它会查看 fst 的定义来决定使用哪个名称。 fst ::(a,b) - >的定义一个,所以 b 将是这里的首选名称,但是由于 b 已经被采用,它附加一个 1 ,使它变成 b1



<我认为这个系统在你不处理任意类型的情况下具有优势,就像这里的情况一样。例如:

  castAdd ::(Num n,Num n1,Num n2)=如果生成的类型看起来像这样, > n  - > n1  - > n2 

...可以说它比以下可读性更强:

  castAdd ::(数字a,数字b,数字c)=> a  - > b  - > c 

...因为您可以主要依靠 n#表示一个数字类型,因为 Num 的类定义是 class Num n其中...



编辑:是的,我知道 castAdd 是不可能实现的,但它只是一个类型示例。 / p>

When using the interactive GHC interpreter, it's possible to ask for the inferred type of an expression:

Prelude> :t map
map :: (a -> b) -> [a] -> [b]

It seems that it takes the names of the type variables from the signature since map is defined as

map :: (a -> b) -> [a] -> [b]
map _ []     = []
map f (x:xs) = f x : map f xs

in the Prelude. That makes a lot of sense! My question is: how are type variable names picked when there is no signature given?

An example would be

Prelude> :t map fst
map fst :: [(b, b1)] -> [b]

where it picked names b and b1. It's clear that renaming must take place, but simply starting with a, b, ... would have given

map fst :: [(a, b)] -> [a]

instead, which I find slightly more readable.

解决方案

As I understand it, ghci chooses names in the same order that it infers the types. It uses the naming scheme as you mentioned to decide the type name of the result, which is [b] because that is the type name specified in the definition of map. It then decides that the function that is the first parameter to map should return something of type b also.

The remaining type variable to be named is thus the type variable for the second element in the argument tuple to fst, and again, it looks at the definition of fst to decide which name to use. The definition of fst :: (a, b) -> a, so b would be the preferred name here, but since b is already taken, it appends a 1 so that it becomes b1.

I think that this system has advantages in situations where you don't deal with arbitrary types as is the case here. If the resulting type looks something like this, for example:

castAdd :: (Num n, Num n1, Num n2) => n -> n1 -> n2

... it is arguably more readable than:

castAdd :: (Num a, Num b, Num c) => a -> b -> c

... because you can mostly rely on that n# signifies a numeric type, since the class definition for Num is class Num n where ....

EDIT: Yes, I know that castAdd is impossible to implement, but it's just a type example.

这篇关于GHCi如何为类型变量选择名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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