我一直在尝试使用 Data.Singletons 库的依赖类型程序,在论文“使用 Singletons 的依赖类型编程”中开发了长度注释向量之后,我遇到了以下问题。
这段代码,不包括 function 的定义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 时获得的大部分便利(注入性、生成性等),但我对这种情况下的问题究竟是什么以及如何规避它的理解非常有限. 我可以指定一些可以清除它的约束吗?