Я экспериментировал с программами с зависимой типизацией, используя библиотеку Data.Singletons, после разработки векторов с аннотациями длины в статье «Зависимо типизированное программирование с синглетонами» и столкнулся со следующей проблемой.
Этот код, за исключением определения функции indexI
, проверяет типы в GHC 7.6.3 и работает, как ожидалось, в его отсутствие:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
import Data.Singletons
import Data.Singletons.TH
data Nat where
Z :: Nat
S :: Nat -> Nat
deriving Eq
$(genSingletons [''Nat])
data FlipList :: * -> * -> Nat -> * where
Cons :: ((a -> b) -> a -> b) -> FlipList a (a -> b) n -> FlipList a b (S n)
Nil :: FlipList a b Z
type family (m :: Nat) :< (n :: Nat) :: Bool
type instance m :< Z = 'False
type instance Z :< (S n) = 'True
type instance (S m) :< (S n) = m :< n
type family PreMap a b (m :: Nat) :: *
type instance PreMap a b Z = a -> b
type instance PreMap a b (S n) = PreMap a (a -> b) n
type family BiPreMap a b (m :: Nat) :: *
type instance BiPreMap a b m = PreMap a b m -> PreMap a b m
index :: ((m :< n) ~ 'True) => SNat m -> FlipList a b n -> BiPreMap a b m
index SZ (Cons f _) = f
index (SS sm) (Cons _ fl) = index sm fl
indexI :: ((m :< n) ~ 'True, SingI m) => FlipList a b n -> BiPreMap a b m
indexI = withSing index
После включения indexI
GHC выдает две ошибки:
Could not deduce (PreMap a b m ~ PreMap a b a0)
from the context ((m :< n) ~ 'True, SingI Nat m)
bound by the type signature for
indexI :: ((m :< n) ~ 'True, SingI Nat m) =>
FlipList a b n -> BiPreMap a b m
а также,
Could not deduce (PreMap a b m ~ PreMap a b a0)
from the context ((m :< n) ~ 'True, SingI Nat m)
bound by the type signature for
indexI :: ((m :< n) ~ 'True, SingI Nat m) =>
FlipList a b n -> BiPreMap a b m
Причина любой ошибки, по-видимому, в том, что термин withSing index
имеет тип FlipList a b n -> BiPreMap a b a0
, и, не имея возможности вывести a0 ~ m
, GHC не может доказать BiPreMap a b m ~ BiPreMap a b a0
. Я знаю, что в выводе типов по семействам типов не хватает большинства удобств, которые мы получаем при работе с ADTS (инъективность, генеративность и т. Д.), Но мое понимание того, в чем именно заключается проблема в этом случае и как ее обойти, очень ограничено. . Могу ли я указать какое-то ограничение, которое может прояснить это?
indexI :: forall m n a b . ((m :< n) ~ 'True, SingI m) => FlipList a b n -> BiPreMap a b m; indexI = withSing (index :: SNat m -> FlipList a b n -> BiPreMap a b m)
- person user2407038   schedule 26.05.2014