- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
GADT好处的典型示例代表DSL的语法;说here on the wiki或the PLDI 2005 paper。
我可以看到,如果您的AST在构造上是正确的,则编写eval
函数很容易。
如何将GADT处理程序构建为REPL?或更具体地说,是进入Read-Parse-Typecheck-Eval-Print-Loop?我看到您只是将eval
步骤的复杂性推到了较早的步骤。
GHCi是否在内部使用GADT表示要评估的表达式? (这些表达式比典型的DSL更加笨拙。)
derive Show
,因此对于“打印”步骤,您可以手动滚动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 b) => Term (a,b) -> Term a
Snd :: (Show a) => Term (a,b) -> Term b
deriving instance (Show a) => Show (Term a)
Show
约束已经无法分离问题了。)eval
函数的便利。任何一个:
Read
实例确实是一项艰巨的工作。所以也许glambda
中用于 pretty-print 的代码涉及几层类和实例。与AST的GADT所声称的优势相反,这里有些不对劲。 (类型正确的)AST的想法是,您同样可以轻松地进行评估:或漂亮地打印它;或对其进行优化;或从中生成代码;等等。
glambda
的目的似乎是评估(鉴于练习的目的,这很公平)。我在想 ...
data Expr = ...
;并迅速遇到类型麻烦。当然,确实做到了;那将永远行不通;几乎任何事情都会比这更好;我感到上当受骗。)data Lit = Lit Int
... data If b a1 a2 = If b a1 a2
...然后是class IsTerm a c | a -> c where ...
(即FunDep
或类型家族,其实例告诉我们术语的结果类型。)IsTerm
实例全部排成一行。 glambda
更糟糕-也就是说,当您考虑整个功能时,不仅要考虑评估步骤。
deriving
可以正常工作。
最佳答案
请注意,GHCi不使用GADT表示表达式。甚至GHC的内部核心表达式类型 Expr
都不是GADT。
DSL
为了使您的Term
类型更加充实,请考虑使用 glambda
。它的 Exp
类型甚至在类型级别上跟踪变量。
UExp
数据类型,正如您所观察到的那样,它是从REPL中实际解析的数据类型。然后,将此类型进行类型检查到Exp
中,并传递给具有以下内容的延续:check :: (MonadError Doc m, MonadReader Globals m)
=> UExp -> (forall t. STy t -> Exp '[] t -> m r)
-> m r
UExp
和Exp
的漂亮字体,但是至少是uses the same code(它通过PrettyExp
类实现)。 hoopl
表示:
data Block n e x where
BlockCO :: n C O -> Block n O O -> Block n C O
BlockCC :: n C O -> Block n O O -> n O C -> Block n C C
BlockOC :: Block n O O -> n O C -> Block n O C
BNil :: Block n O O
BMiddle :: n O O -> Block n O O
BCat :: Block n O O -> Block n O O -> Block n O O
BSnoc :: Block n O O -> n O O -> Block n O O
BCons :: n O O -> Block n O O -> Block n O O
String
(或自定义REPL)构建的,则执行翻译的时间会很艰难。这是不可避免的,因为您要做的实际上是重新实现一个简单的类型检查器。 最好的选择是直面这个问题(就像
glambda
一样),并从类型检查中区分解析。
关于haskell - DSL的GADT : swings and roundabouts?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54919548/
这三者之间有什么/为什么有区别? GADT(和常规数据类型)只是数据系列的简写吗?具体有什么区别: data GADT a where MkGADT :: Int -> GADT Int dat
我们能否将构造函数没有给定约束的 GADT 转换为具有上述约束的 GADT?我想这样做是因为我想要深度嵌入箭头,并使用(目前)似乎需要 Typeable 的表示来做一些有趣的事情。 (One reas
我试图将 mod-n 计数器表示为将间隔 [0, ..., n-1] 分成两部分: data Counter : ℕ → Set where cut : (i j : ℕ) → Counter (
这是一个示例代码: {-# LANGUAGE GADTs #-} data NumGadt a where NumGadt :: Num a => a -> Int -> String -> Bo
我为表达式创建了一个 GADT。当我对具有约束的构造函数进行模式匹配时,类型检查器无法推断构造函数约束中使用的类型变量的约束。我认为代码和错误消息更清楚。 {-# LANGUAGE GADTs, Mu
背景 我正在使用 Haskell 编写一个红黑树实现 依赖类型并且我在理解为什么下面的代码不起作用时遇到了一些麻烦。作为一种热身练习,我想做的是找到一个给定任意值的子树。不幸的是,我在编译代码并最终继
在他的论文 Generics for the Masses Hinze 回顾了数据类型的编码。 从 Nat 开始 data Nat :: ⋆ where Zero :: Nat Succ
当我尝试创建一个返回 Thing a 的函数时,我目前正与类型检查器发生冲突。 (其中 Thing 是 GADT)。一个最小的人为例子: {-#LANGUAGE GADTs, EmptyDataDec
考虑以下代码 data Foo f where Foo :: Foo Int class DynFoo t where dynFoo :: Foo f -> Foo t instance Dy
假设我正在编写一个 DSL,并希望同时支持幻像类型和错误类型的表达式。我的值(value)类型可能是 {-# LANGUAGE GADTs, DataKinds #-} data Ty = Num |
当answering a question with a suggestion to use GADTs ,评论中出现了一些关于性能的问题。问题涉及类型类 PlotValue : class Plot
我只是在阅读Dependent Types at Work .在参数化类型的介绍中,作者提到在这个声明中 data List (A : Set) : Set where [] : List A
考虑以下代码: data (:+:) f g a = Inl (f a) | Inr (g a) data A data B data Foo l where Foo :: Foo A data
是分机GADT在 Haskell 中破坏多态性,即使在不使用 GADT 的代码中? 这是一个有效但不使用 GADT 的示例 {-# LANGUAGE RankNTypes #-} --{-# LANG
这两个 GADT 声明之间有区别吗? data A a b where ... data A :: * -> * -> * where ... 最佳答案 没有区别。有人可能会认为,在构
我在 haskell 中建立了一个几何库。我不打算发布它,它只是我用来提高我的语言知识的一个项目。 我有一个 Local数据类型,定义如下 data Local a where MkLocal
我正在阅读 GADTs for dummies Haskell Wiki 上的页面,我仍然不明白如何以及为什么应该使用它们。作者举了一个励志的例子: data T a where D1 ::
我正在解析表单的一些语句 v1 = expression1 v2 = expression2 ... 我正在使用 State Monad 并且我的状态应该是一对 (String, Expr a),我真
如何使用广义代数数据类型? haskell wikibook 中给出的示例太短了,无法让我深入了解 GADT 的真正可能性。 最佳答案 我发现“Prompt”monad(来自“MonadPrompt”
我正在使用 learnyouahaskell 来介绍 GADT,并且我对它们可能的用途很感兴趣。据我了解,它们的主要特点是允许显式类型设置。 如: data Users a where GetUs
我是一名优秀的程序员,十分优秀!