I'm playing with Haskell, the idea were to create a toy language with help of GADTs. Interpreters usually have an environment mapping that maps variables names to values.
I have basically two types in my toy language int and bool represented by I 10
and B True
for example.
The problem is that I can't create a map that hold both of these, here is my code
{-# 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)]’
How can I create such mapping?
Either (Expr Int) (Expr Bool)
? But if not, you can use existential types:newtype SomeExpr = forall a. SomeExpr (Expr a)
, then make it a list ofSomeExpr
s. – bradrn