首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell: AST减少导致类型问题

Haskell: AST减少导致类型问题
EN

Stack Overflow用户
提问于 2018-03-11 05:38:51
回答 1查看 114关注 0票数 1

下面是可扩展AST的代码。我的目标是允许以后在Expr类中添加更多的表达式类型,而不是在单个数据块中添加所有类型。

代码语言:javascript
复制
data Constant o = Constant o deriving (Show)
data Add l r o = Add (l o) (r o) deriving (Show)

class Expr e where
  simplify :: (Expr a, Num o) => (e o) -> (a o)

instance Expr Constant where
  simplify (Constant a) = Constant a

instance (Expr l, Expr r) => Expr (Add l r) where
  simplify (Add l r) = case (simplify l, simplify r) of
    (Conatant a, Constant b) -> Constant $ a + b
    (sl@_, sr@_) -> Add sl sr

我遇到了这些错误:

代码语言:javascript
复制
math.hs:10:27: error:
    • Couldn't match type ‘a’ with ‘Constant’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          simplify :: forall (a :: * -> *) o.
                      (Expr a, Num o) =>
                      Constant o -> a o
        at math.hs:10:3-10
      Expected type: a o
        Actual type: Constant o
    • In the expression: Constant a
      In an equation for ‘simplify’: simplify (Constant a) = Constant a
      In the instance declaration for ‘Expr Constant’
    • Relevant bindings include
        simplify :: Constant o -> a o (bound at math.hs:10:3)

math.hs:15:21: error:
    • Couldn't match type ‘a’ with ‘Add l0 r0’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          simplify :: forall (a :: * -> *) o.
                      (Expr a, Num o) =>
                      Add l r o -> a o
        at math.hs:13:3-10
      Expected type: a o
        Actual type: Add l0 r0 o
    • In the expression: Add sl sr
      In a case alternative: (sl@_, sr@_) -> Add sl sr
      In the expression:
        case (simplify l, simplify r) of { (sl@_, sr@_) -> Add sl sr }
    • Relevant bindings include
        sr :: r0 o (bound at math.hs:15:12)
        sl :: l0 o (bound at math.hs:15:6)
        simplify :: Add l r o -> a o (bound at math.hs:13:3)

我不明白为什么这不管用。再说一次,我对哈斯克尔来说还是个新手,因为我在OOP的土地上花了将近十年的时间。我希望有人能给我一些洞察力。

我试图在没有任何GHC扩展的情况下做到这一点,因为在我开始添加更多之前,我想了解普通语言。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-11 05:57:52

代码语言:javascript
复制
class ... where
  simplify :: (Expr a, ...) => ... -> (a o)

此声明意味着您无法为类Expr中的任何类型(按a o的用法选择)构造simplify。不能在实例中指定具体类型。

编辑:您可以在Expr中引入一个构造:

代码语言:javascript
复制
class Expr e where
    ...
    constant :: a -> e a
    add :: e a -> e a -> e a
    ...

然后用这些。虽然像(add __ ::常数Int)这样的表达式没有意义。

您可以做的是使用依赖项指定类

代码语言:javascript
复制
class Simplify e1 e2 | e1 -> e2 where ...

或的家族类型

代码语言:javascript
复制
class Simplify e where
    data Simplified e :: *
    ....

它们需要相应的扩展,但是您不应该害怕它。现代哈斯克尔就是这样。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49217019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档