В дополнение к ответу TomMD, вы можете использовать Agda для того же эффекта.Хотя у него нет классов типов, вы получаете большую часть функциональности (кроме динамической отправки) из записей.
record Direction (a : Set) : Set₁ where
field
turnLeft : a → a
turnRight : a → a
commLaw : ∀ x → turnLeft (turnRight x) ≡ turnRight (turnLeft x)
Я решил отредактировать пост и ответить на вопрос, почему выне может сделать это в Haskell.
В Haskell (+ расширения) вы можете представить эквивалентность, как в приведенном выше коде Agda.
{-# LANGUAGE GADTs, KindSignatures, TypeOperators #-}
data (:=:) a :: * -> * where
Refl :: a :=: a
Это представляет теоремы о равенстве двух типов,Например, a
эквивалентно b
, равно a :=: b
.
Там, где мы эквивалентны, мы можем использовать конструктор Refl
.Используя это, мы можем выполнять функции для доказательств (значений) теорем (типов).
-- symmetry
sym :: a :=: b -> b :=: a
sym Refl = Refl
-- transitivity
trans :: a :=: b -> b :=: c -> a :=: c
trans Refl Refl = Refl
Все они корректны по типу и, следовательно, верны.Однако это;
<code>wrong :: a :=: b
wrong = Refl
явно неверно и действительно не проходит проверку типов.
Однако, несмотря на все это, барьер между значениями и типамине был сломан.Значения, функции уровня значений и доказательства все еще живут на одной стороне двоеточия;типы, функции уровня типа и теоремы живут на другом.Ваши turnLeft
и turnRight
являются функциями уровня значений и поэтому не могут быть включены в теоремы.
Agda и Coq являются языками с зависимой типизацией, гдебарьер не существует или вещи могут пересекать Strathclyde Haskell Enhancement (SHE) - это препроцессор для кода на Haskell, который может обманывать некоторые эффекты DTP в Haskell.Это достигается путем дублирования данных из мира значений в мире типов.Я не думаю, что он обрабатывает дублирующие функции на уровне значений, и если бы он это сделал, я догадываюсь, что это может быть слишком сложно для него.