Насколько я понимаю, ghci
выбирает имена в том же порядке, что и типы.Он использует схему именования, как вы упомянули, для определения имени типа результата, которое равно [b]
, потому что это имя типа, указанное в определении map
.Затем он решает, что функция, которая является первым параметром для map
, должна также возвращать что-то типа b
.
Оставшаяся переменная типа, которая должна быть названа, таким образом, является переменной типа для второго элемента в аргументекортеж к fst
, и снова, он смотрит на определение fst
, чтобы решить, какое имя использовать.Определение fst :: (a, b) -> a
, поэтому b
было бы предпочтительным именем здесь, но поскольку b
уже занято, к нему добавляется 1
, так что оно становится b1
.
Я думаю, чтоэта система имеет преимущества в ситуациях, когда вы не имеете дело с произвольными типами, как здесь.Если результирующий тип выглядит примерно так, например:
castAdd :: (Num n, Num n1, Num n2) => n -> n1 -> n2
... он, возможно, более читабелен, чем:
castAdd :: (Num a, Num b, Num c) => a -> b -> c
... потому что вы в основном можете полагаться на этоn#
обозначает числовой тип, поскольку определение класса для Num
равно class Num n where ...
.
РЕДАКТИРОВАТЬ: Да, я знаю, что castAdd
невозможно реализовать, но это всего лишь пример типа.