Изучай Haskell обсуждает newtype
.
Как его сигнатура Pair b a
означает, что переданный аргумент должен быть кортежем?
ghci> newtype Pair b a = Pair { getPair :: (a, b) }
ghci> let p = Pair (5, 10)
Я запутался, как b a
указывает на кортеж.
Изучай Haskell обсуждает newtype
.
Как его сигнатура Pair b a
означает, что переданный аргумент должен быть кортежем?
ghci> newtype Pair b a = Pair { getPair :: (a, b) }
ghci> let p = Pair (5, 10)
Я запутался, как b a
указывает на кортеж.
Причина, по которой вы передаете кортеж, не в типе, а в его конструкторе:
Pair { getPair :: (a, b) }
Это использует синтаксис записи для определения конструктора Pair
с одним полем под названием getPair
, которое содержит кортеж. Вы можете получить очень похожий эффект, разбив его на две части:
newtype Pair b a = Pair (a, b)
getPair (Pair (x, y)) = (x, y)
Таким образом, b a
не делает его кортежем; это то, что делает { getPair :: (a, b) }
.
Путаница возникает из-за того, что у вас есть имя типа данных и имя конструктора, указанные как Pair
. Вместо этого вы могли бы эквивалентно написать
newtype Pair b a = MkPair { getPair :: (a, b) }
Тогда вы бы построили его с помощью
> let p = MkPair ("test", 10) :: Pair Int String
Конструкторы и имена типов не имеют общих пространств имен, поэтому они могут иметь одно и то же имя без конфликтов. Этот шаблон часто используется для новых типов, поскольку имя типа обычно является хорошим описательным именем и для конструктора. Это также работает для типов, объявленных с ключевым словом data
.