我在和Haskell玩,我的想法是在GADT的帮助下创建一种玩具语言。解释器通常有一个将变量名映射到值的环境映射。
在我的玩具语言中,基本上有两种类型,例如用I 10和B True表示的int和bool。
问题是我不能创建同时包含这两个元素的地图,以下是我的代码
{-# LANGUAGE GADTs, RankNTypes #-}
module Foo where
import qualified Data.Map as M
import Data.Maybe
data Expr a where
V :: Char -> Expr a
B :: Bool -> Expr Bool
I :: Int -> Expr Int
If :: Expr Bool -> Expr a -> Expr a -> Expr a
type Env a = M.Map Char (Expr a)
env = M.fromList [('x', B True), ('y', I 10)]
-- Error here ----^^^^
-- [typecheck -Wdeferred-type-errors] [E] • Couldn't match type ‘Int’ with ‘Bool’
-- Expected type: Expr Bool
-- Actual type: Expr Int
-- • In the expression: I 10
-- In the expression: ('y', I 10)
-- In the first argument of ‘M.fromList’, namely
-- ‘[('x', B True), ('y', I 10)]’如何创建这样的映射?
发布于 2021-08-26 03:02:17
对于如此小的类型集合,我将使用以下其中之一:
type Env = Map Variable (Either (Expr Int) (Expr Bool))
type Env = (Map Variable (Expr Int), Map Variable (Expr Bool))关于是否要为每种类型使用单独的命名空间的...depending。当有更多类型可用时,我会使用这些类型之一:
data UntypedExpr = forall a. UE (TypeRep a) (Expr a)
type Env = Map Variable UntypedExpr
-- OR
newtype SingleTypeEnv a = STE (Map Variable (Expr a))
type Env = TypeRepMap SingleTypeEnv...again取决于是否要为每种类型使用单独的命名空间。
TypeRep来自基本包(或者您可以编写一些新的GADT,它更针对您的EDSL的类型),而TypeRepMap来自typerep-map。
https://stackoverflow.com/questions/68931850
复制相似问题