Добрый полиморфизм в семьях закрытого типа - PullRequest
3 голосов
/ 26 апреля 2020

Я пытался реализовать семейство типов Ty на бумаге Generi c Программирование всех видов , которое вычисляет тип Atom. Сначала я попытался использовать семейство закрытых типов так же, как в статье:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}

module GenericK where

import Data.Kind

type Kind = Type

-- | TyVar represents type parameters that the data takes
data TyVar (zeta :: Kind) (k :: Kind) :: Type where
  VZ :: TyVar (x -> xs) x
  VS :: TyVar xs k -> TyVar (x -> xs) k

-- | Atom is similar to K1
data Atom (zeta :: Kind) (k :: Kind) :: Type where
  Var :: TyVar zeta k -> Atom zeta k
  Kon :: k -> Atom zeta k
  (:@:) :: Atom zeta (l -> k) -> Atom zeta l -> Atom zeta k

--| Gamma is a context
data Gamma (zeta :: Kind) where
  Eta :: Gamma Type
  (:&:) :: k -> Gamma ks -> Gamma (k -> ks)

type family Ty zeta (alpha :: Gamma zeta) (t :: Atom zeta k) :: k where
  Ty (k -> ks) (t :&: alpha) (Var VZ) = t
  Ty (k -> ks) (t :&: alpha) (Var (VS v)) = Ty ks alpha (Var v)
  Ty zeta alpha (Kon t) = t
  Ty zeta alpha (f :@: x) = (Ty zeta alpha f) (Ty zeta alpha x)

Однако GH C пожаловался:

• Expected kind ‘Atom zeta k’,
    but ‘f’ has kind ‘Atom zeta (k -> k)’
• In the third argument of ‘Ty’, namely ‘f’
  In the type ‘(Ty zeta alpha f) (Ty zeta alpha x)’
  In the type family declaration for ‘Ty’

Сообщение об ошибке не имеет особого смысла мне ясно, что f должен иметь вид Atom zeta (l -> k), а x должен иметь вид Atom zeta l.

Так что я попытался использовать семейство открытых типов, и это сработало:

type family Ty zeta (alpha :: Gamma zeta) (t :: Atom zeta k) :: k

type instance Ty (k -> ks) (t :&: alpha) (Var VZ) = t
type instance Ty (k -> ks) (t :&: alpha) (Var (VS v)) = Ty ks alpha (Var v)
type instance Ty zeta alpha (Kon t) = t
type instance Ty zeta alpha (f :@: x) = (Ty zeta alpha f) (Ty zeta alpha x)

Мне любопытно, почему семья закрытого типа не работала. Я думаю, это может быть связано с добрым полиморфизмом, но я не знаю, как работает проверка вида в GH C.

...