GADT的优点的典型示例代表DSL的语法; 说这里的维基或在PLDI 2005年纸.
我可以看到,如果你通过构造得到一个类型正确的AST,那么编写一个eval函数很容易.
如何将GADT处理构建到REPL中?或者更具体地说是Read-Parse-Typecheck-Eval-Print-Loop?我看到你只是将eval步骤的复杂性推到了前面的步骤中.
GHCi是否在内部使用GADT来表示它正在评估的表达式?(表达式比典型的DSL要厚很多.)
首先,您不能derive Show使用GADT,因此对于Print步骤,您可以手动滚动Show实例或类似的内容:
{-# LANGUAGE GADTs, StandaloneDeriving #-}
data Term a where
Lit :: Int -> Term Int
Inc :: Term Int -> Term Int
IsZ :: Term Int -> Term Bool
If :: Term Bool -> Term a -> Term a -> Term a
Pair :: (Show a, Show b) => Term a -> Term b -> Term (a,b)
Fst :: (Show …Run Code Online (Sandbox Code Playgroud)以下代码旨在将布尔型的Church编码打印为Haskell的Bool:
{-#LANGUAGE FlexibleInstances #-}
instance Show (t -> t -> t) where
show b = show $ b True False
Run Code Online (Sandbox Code Playgroud)
导致此错误:
<interactive>:4:21: error:
• Couldn't match expected type ‘t’ with actual type ‘Bool’
‘t’ is a rigid type variable bound by
the instance declaration at <interactive>:3:10-27
• In the first argument of ‘b’, namely ‘True’
In the second argument of ‘($)’, namely ‘b True False’
In the expression: show $ b True False
• Relevant bindings include
b …Run Code Online (Sandbox Code Playgroud)