我試圖在Haskell中進行依賴類型編程,特別是類型安全查找操作。 Previously,我問過有關如何實現以下數據類型的查找操作:有關Haskell中異類列表的類型安全查找的更多信息
data Attr (xs :: [(Symbol,*)]) where
Nil :: Attr '[]
(:*) :: (Sing s, t) -> Attr xs -> Attr ('(s , t) ': xs)
而且我得到了答案:
lookupAttr :: (Lookup s env ~ 'Just t) => Sing s -> Attr env -> t
lookupAttr s ((s', t) :* env') = case s %:== s' of
STrue -> t
SFalse -> lookupAttr s env'
這工作正常。現在,我想通過Exp
類型來定義類型的語法的值的異質列表,表示:
{-# LANGUAGE GADTs, TypeFamilies, DataKinds, TypeOperators, PolyKinds #-}
import Data.Singletons.Prelude.List
import Data.Singletons.Prelude.Bool
import Data.Singletons.Prelude.Eq
data Exp (env :: [(Symbol,*)]) :: * -> * where
Value :: String -> Exp env String
Var :: (Lookup s env ~ 'Just t) => Sing s -> Exp env t
Op :: Exp env t -> Exp env t -> Exp env t
將不均勻列表類型由Env
數據類型定義:
data Env (env :: [(Symbol,*)]) where
Nil :: Env '[]
Cons :: (Lookup s' env ~ 'Nothing) =>
(Sing s' ,
Exp ('(s', a) ': env) a) ->
Env env ->
Env ('(s',a) ': env)
使用這些數據類型,我定義使用某種存在量化的查找功能(輸入Ex2
):
data Ex2 (p :: k -> k' -> *) where
Ex2 :: p e i -> Ex2 p
lookupEnv :: Lookup s env ~ 'Just t => Sing s -> Env env -> Ex2 Exp
lookupEnv s (Cons (s',e) env)
= case s %:== s' of
STrue -> Ex2 e
SFalse -> lookupEnv s env
到目前爲止, 太好了。現在,我遇到了一些有趣的問題:
1)有沒有辦法定義lookupEnv
而不使用這種類型Ex2
提供的存在量化?
2)假設我想定義一個操作來修改類型爲Env
的值的給定條目。明顯試圖定義該函數是
modifyEnv :: Lookup s env ~ 'Just t => Sing s -> Exp env t -> Env env -> Env env
modifyEnv s e (Cons (s',e') env')
= case s %:== s' of
STrue -> Cons (s', Op e e') env'
SFalse -> Cons (s',e') (modifyEnv s e env')
功能modifyEnv
構成一些表達與另一環境。 GHC不接受這個函數,它返回一個神祕的錯誤信息。我怎樣才能定義這種修改功能?
Hi @Cactus!感謝您的回答!我已經考慮過使用類型化的DeBruijn索引,但是EDSL用戶手工構建起來有點複雜(我的最終目標是構建EDSL)。因此,我試圖使用符號索引環境。 –