Подтвердить что ты не робот

Что вы использовали для более ранних типов в Haskell?

Более высокие классы рангов выглядят очень весело. Из Haskell wikibook приведен этот пример:

foo :: (forall a. a -> a) -> (Char,Bool)
foo f = (f 'c', f True)

Теперь мы можем оценить foo id без взрыва компилятора. Этот пример быстро следует в книге примером реального мира, который я видел в нескольких других местах: ST monad и runST. Это довольно круто.

Но мне еще предстоит встретить ситуацию, когда я решаю проблему, написав свою собственную функцию с аргументом более высокого ранга. У вас есть? Какие примеры у вас в полиморфизме ранга 2 или ранга-n в дикой природе?

4b9b3361

Ответ 1

Посмотрите на функции типа withRepoLock в источнике Darcs.

Darcs поддерживает несколько форматов репозитория, и эта поддержка выражается через класс типов. Таким образом, вы можете написать код, который является общим для форматов репозитория. Когда вы действительно читаете репозиторий на диске, который хотите отправить в этот код через какой-то общий код, который определяет формат, в котором находится репозиторий, и выбирает правильную копию экземпляра типа.

Ответ 2

Вейрих и Уошберн "Коробки идут бананы"! (paper, слайды)

Вот очень грубое и, вероятно, немного неточное объяснение того, что все это значит: учитывая индуктивный тип, BGB позволяет вам представлять пространство функций из этого типа, которые являются "положительными" - они никогда не различаются по своим аргументам, В большинстве случаев они включают их аргументы как часть других значений (обычно одного типа).

Weirich + Washburn использовать это, чтобы получить возможное адекватное представление HOAS лямбда-исчисления в -XRankNTypes Haskell (кто-нибудь еще доказал его адекватность?).

Я использую его здесь (предупреждение: messy code), чтобы включить

(forall g . GArrow g => g () x -> g () y)

в

(forall g . GArrow g => g x y)

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

Вы не можете сделать это с помощью класса Control.Arrow, потому что все функциональное пространство Haskell "просачивается" в него через arr.

Ответ 4

Возможно, вы столкнулись с проблемами, когда более ранжированные типы были бы полезны, но не смогли это реализовать. Например, в примере Darcs они могли легко реализовать его без более ранжированных типов. Вместо этого были бы предпосылки для некоторых функций, которые вызывающий должен был бы удостовериться в том, что они соблюдают такие правила, как выбор правильного экземпляра функции для формата репозитория.

Преимущество более ранжированного типа заключается в том, что он переносит ответственность за получение этого права от программиста до компилятора. При использовании обычного подхода, если разработчик Darcs допустил ошибку с типом репозитория, результатом будет либо ошибка времени выполнения, либо поврежденные данные. С более высоким ранжированным типом разработчик получает ошибку типа во время компиляции.