我正在玩Haskell,我的想法是在GADT的幫助下創建一種玩具語言。解釋器通常有一個環境映射,將變數名稱映射為數值。
在我的玩具語言中,基本上有兩種型別int和bool,例如用I 10和B True表示。
問題是,我無法創建一個可以容納這兩種型別的地圖,以下是我的代碼
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)]
-- 錯誤在這里 ----^^^^]
-- [typecheck -Wdeferred-type-errors] [E] - 無法用'Bool'匹配'Int'型別。
-- 預期的型別。Expr Bool
-- 實際型別。Expr Int
-- - 在運算式中。I 10
-- 在運算式中。('y', I 10)
-- 在'M.fromList'的第一個引數中,即。
-- '[('x', B True), ('y', I 10)]'
我如何創建這樣的映射?
uj5u.com熱心網友回復:
對于這樣一個小的型別集合,我將使用其中的一種:
type Env =Map Variable (Either (Expr Int) (Expr Bool))/span>
type Env = (Map) type">Map Variable (Expr Int)。Map Variable (Expr Bool))
......這取決于你是否想為每個型別建立單獨的命名空間。當有更多的型別可用時,那么我將使用其中的一個:
data UntypedExpr = forall a。UE (TypeRep a) (Expr a)/span>
type Env = Map Variable UntypedExpr
--OR
newtype SingleTypeEnv a = STE (Map Variable (Expr a))
type Env = TypeRepMap SingleTypeEnv
......同樣取決于你是否要為每個型別建立單獨的命名空間。
TypeRep來自基礎包(或者你可以編造一些新的GADT,更具體地針對你的EDSL的型別),而TypeRepMap來自typerep-map.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/316958.html
標籤:
上一篇:使用haskell根據兩個相鄰位置的另一個欄位的值之差來計算一個欄位的值
下一篇:一個類中的多個型別同義詞
