How do I apply inductive reasoning to `GHC.TypeLits.Nat`?

江枫思渺然 提交于 2019-12-03 15:36:02

There is no induction on TypeLits, which by default does make them nearly useless, but you can improve the situation in two ways.

Use ghc-typelits-natnormalise. It's a GHC plugin which adds an arithmetic solver to the type checker, and causes GHC to consider many equal Nat expressions equal. This is very convenient and is compatible with the next solution. Your zip works with this out of the box.

Postulate whatever properties you need. You should only postulate proofs of true statements, and only proofs of equalities or other computationally irrelevant data types, in order to avoid potential memory safety issues. For example, your zip works the following way:

{-# language
    RankNTypes, TypeApplications, TypeOperators,
    GADTs, TypeInType, ScopedTypeVariables #-}

import GHC.TypeLits
import Data.Type.Equality
import Unsafe.Coerce

data Vector (n :: Nat) a
  where
    VZ :: Vector 0 a
    (:::) :: a -> Vector n a -> Vector (n + 1) a

lemma :: forall n m k. (n :~: (m + 1)) -> (n :~: (k + 1)) -> m :~: k
lemma _ _ = unsafeCoerce (Refl @n)

vzip :: Vector n a -> Vector n b -> Vector n (a, b)
vzip VZ VZ = VZ
vzip ((a ::: (as :: Vector m a)) :: Vector n a)
     ((b ::: (bs :: Vector k b)) :: Vector n b) =
  case lemma @n @m @k Refl Refl of
    Refl -> (a, b) ::: vzip as bs
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!