首先,我从一些典型的类型级自然数字开始。
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
data Nat = Z | S Nat
type family Plus (n :: Nat) (m :: Nat) :: Nat
type instance Plus Z m = m
type instance Plus (S n) m = S (Plus n m)
所以我想创建一个表示n维网格的数据类型。 (对Evaluating cellular automata is comonadic所见内容的概括。)
data U (n :: Nat) x where
Point :: x -> U Z x
Dimension :: [U n x] -> U n x -> [U n x] -> U (S n) x
我们的想法是,U num x
类型是num
的{{1}}维网格的类型,它“聚焦”在网格中的特定点上。
所以我想把它变成一个comonad,我注意到我可以做这个潜在有用的功能:
x
我们现在可以实现一个“维度连接”,根据这个组合子,将m维网格的n维网格转换为(n + m)维网格。在处理将产生网格网格的ufold :: (x -> U m r) -> U n x -> U (Plus n m) r
ufold f (Point x) = f x
ufold f (Dimension ls mid rs) =
Dimension (map (ufold f) ls) (ufold f mid) (map (ufold f) rs)
的结果时,这将派上用场。
cojoin
到目前为止一切顺利。我还注意到dimJoin :: U n (U m x) -> U (Plus n m) x
dimJoin = ufold id
实例可以用Functor
。
ufold
但是,这会导致类型错误。
instance Functor (U n) where
fmap f = ufold (\x -> Point (f x))
但是如果我们掀起一些复制意大利面,那么类型错误就会消失。
Couldn't match type `n' with `Plus n 'Z'
我讨厌复制意大利面的味道,所以我的问题是这个。 如何判断instance Functor (U n) where
fmap f (Point x) = Point (f x)
fmap f (Dimension ls mid rs) =
Dimension (map (fmap f) ls) (fmap f mid) (map (fmap f) rs)
等于Plus n Z
的类型系统?问题是:您不能对类型系列实例进行更改,这会导致n
产生类似的类型错误。
答案 0 :(得分:5)
你需要的是一个很好的命题相等类型:
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
data Nat = Z | S Nat
type family Plus (n :: Nat) (m :: Nat) :: Nat
type instance Plus Z m = m
type instance Plus (S n) m = S (Plus n m)
data (:=) :: k -> k -> * where
Refl :: a := a
data Natural (n :: Nat) where
Zero :: Natural Z
Suc :: Natural n -> Natural (S n)
plusZero :: Natural n -> n := (n `Plus` Z)
plusZero Zero = Refl
plusZero (Suc n) | Refl <- plusZero n = Refl
这允许您通过Refl
上的模式匹配来证明关于您的类型的任意事物,并将这些知识带入本地范围。
一个令人讨厌的事情是我的plusZero
证明要求对自然问题进行归纳,默认情况下你无法做到(因为它在运行时不存在)。但是,生成Natural
证人的类型类很容易。
您的特定情况的另一个选项可能只是在您的类型定义中将参数反转为加号,以便您在左侧获得Z
并自动减少。确保你的类型尽可能简单,这通常是一个很好的第一步,但是无论如何你都经常需要命题平等来处理更复杂的事情。