Недостаток продуктов неподъемного типа?

В Haskell продукты поднятого типа означают, что существует семантическая разница между (a,b,c) и (a, (b, c)).

Если бы все совпадения с образцами всех продуктов всегда были неопровержимыми, тогда не было бы никакой разницы, и (a, b, c) могло бы быть синтаксическим сахаром для (a, (b, c)).

Почему Haskell выбрала продукты типа lift?


person Peaker    schedule 21.03.2010    source источник
comment
Потому что плоский кортеж менее полезен?   -  person kennytm    schedule 21.03.2010
comment
Под сплющиванием ты имеешь в виду неподнятый? Если да, то почему? Мне это не кажется очевидным, а неподнятый кортеж обладает лучшими формальными алгебраическими свойствами.   -  person Reid Barton    schedule 21.03.2010
comment
Я бы предпочел, чтобы это был синтаксический сахар для (a, (b, (c, ()))), например HList   -  person yairchu    schedule 23.03.2010


Ответы (3)


Одна из причин заключается в том, что реализация seq для неподнятого продукта требует параллельных/чередующихся вычислений, поскольку seq (a, b) True предполагается равным True тогда и только тогда, когда хотя бы одно из a и b не является нижним. Вы можете не найти эту причину ужасно убедительной, в зависимости от того, как вы относитесь к seq, но, конечно, полиморфный seq по определению является частью Haskell...

person Reid Barton    schedule 21.03.2010
comment
Я думаю, что seq должен использовать класс типов, и я думаю, что seq в его текущей форме должно быть разрешено завершать расходящуюся программу, а не наоборот. - person Peaker; 21.03.2010
comment
IOW, у меня нет проблем с seq (_|_, _|_) True == True, даже если кортежи не подняты. - person Peaker; 21.03.2010
comment
В этот момент вы могли бы просто не делать (a,b) экземпляром Seq (и то же самое для a -> b). - person Reid Barton; 21.03.2010
comment
Это может быть слишком ограничительным. Тривиальный экземпляр позволил бы использовать кортежи и функции в большем количестве случаев, даже если это означает, что seq не работает. Я думаю, что желаемые свойства seq работают. Кто-нибудь использует его из-за его денотативных качеств? - person Peaker; 21.04.2011
comment
Я узнал ответ на свой вопрос: да, люди используют seq из-за его денотативной семантики. Если вы хотите гарантировать, что доказательство, которое вы получили, действительно является доказательством. Хотя в этом случае они могут просто использовать rnf, который будет действителен для большинства доказательств и также действителен в случае (|, |). - person Peaker; 05.06.2011

Почему Haskell выбрала продукты типа lift?

Вы можете обосновать этот выбор дизайна, не апеллируя к лени или опровержимым шаблонам. Тот же выбор дизайна сделан ML из соображений поддержки полиморфизма. Рассмотреть возможность

fst (x, y) = x
snd (x, y) = y

Теперь, если (a, (b, c)) является синтаксическим сахаром для (a, b, c), довольно сложно понять, как специализировать fst и snd, чтобы использовать этот тип в качестве аргумента. Но

fst :: (a, (b, c)) -> a
snd :: (a, (b, c)) -> (b, c)

вполне разумны. Поскольку полиморфные функции, такие как fst и snd, невероятно полезны, и Haskell, и ML дают программисту возможность отличать (a, (b, c)) и ((a, b), c) от (a, b, c).

(Для людей, которые заботятся о затратах, структура типов также является разумным ориентиром для определения размера типа и количества косвенных обращений (загрузок), необходимых для получения его элементов. Некоторым программистам необходимо или они хотят знать о таких вещах и иметь некоторые небольшая степень контроля над ними.)

person Norman Ramsey    schedule 22.03.2010
comment
Вы отвечаете, почему (a,b,c) не изоморфно (a,(b,c)) (или, что проще для работы, (a,(b,(c,()))))), но не почему типовые продукты не поднимаются. Подъем означает добавление дна, делающее (неопределенное, неопределенное) отличным от неопределенного. - person luqui; 23.03.2010
comment
@luqui: Согласен. Я решил обратиться к той части вопроса, которая фокусируется на семантической разнице между (a, (b, c)) и (a, b, c). Когда на это различие обращают внимание, поднятие становится очевидным — поднимаются кортежи, потому что поднимается каждый тип. - person Norman Ramsey; 24.03.2010

Вы можете создать семантическое различие, если хотите, в связи с классами типов.

(a, b, c) и (a, (b, c)) могут создавать экземпляры классов по-разному. Просто подумайте о

show (1, 2, 3)

а также

show (1, (2, 3))

Я бы посчитал нелогичным, чтобы оба давали один и тот же результат.

person Dario    schedule 21.03.2010
comment
Мне это действительно очень не нравится. Это вызывает взрыв N-кортежей (например: см. :info Show в ghci) и делает невозможным создание экземпляров только (a, b), чтобы получить экземпляры для всех кортежей. Я действительно не хочу иметь другую семантику для (a, b, c), чем (a, (b, c)). Я желаю шоу для обоих только что вернувшихся (a, b, c). Кроме того, несоставимость N-кортежей действительно раздражает. Нам нужно иметь миллион вариантов fst и snd, Control.Arrow.first/second, аксессоров кортежей Data.Accessor и т.д. - person Peaker; 21.03.2010