Я играю с тем, что предлагает haskell для зависимого программирования. Я продвинул GADT, представляющий натуральные числа, на добрый уровень и сделал семейство типов для добавления натуральных чисел. Я также сделал ваш стандартный вектор "ребенок первого зависимого типа данных", параметризованный как по его длине, так и по типу, который он содержит. Код выглядит следующим образом:
data Nat where
Z :: Nat
S :: Nat -> Nat
type family (a :: Nat) + (b :: Nat) :: Nat where
Z + n = n
S m + n = S (m + n)
data Vector (n :: Nat) a where
Nil :: Vector Z a
Cons :: a -> Vector n a -> Vector (S n) a
Кроме того, я сделал функцию append
которая принимает m -vector, n-vetor и возвращает (m + n) -vector. Это работает так же, как можно было бы надеяться. Однако, просто для этого, я попытался перевернуть его, чтобы он возвращал (n + m) -vector. Это приводит к ошибке компилятора, поскольку GHC не может доказать, что мое добавление является коммутативным. Я по-прежнему относительно новый, чтобы набирать семьи, поэтому я не уверен, как написать это доказательство самостоятельно, или если это даже то, что вы можете сделать в haskell.
Моя первоначальная мысль заключалась в том, чтобы каким-то образом использовать ограничение равенства типов, но я не уверен, как двигаться вперед.
Поэтому, чтобы быть ясным: я хочу написать эту функцию
append :: Vector m a -> Vector n a -> Vector (n + m) a
append Nil xs = xs
append (Cons x xs) ys = x 'Cons' append xs ys
но он не скомпилирован с
* Could not deduce: (n + 'Z) ~ n
from the context: m ~ 'Z
bound by a pattern with constructor: Nil :: forall a. Vector 'Z a,
in an equation for 'append'