代码之家  ›  专栏  ›  技术社区  ›  usr

Haskell问题:将数据类型约束为使用Show

  •  3
  • usr  · 技术社区  · 15 年前

    代码:

    data Exp a = Const a | Eq (Exp a) (Exp a)
    

    我想要 常数A 包含类型为show的值,以便稍后打印。所以在C中我会写:

    class Const : Exp { IShow X; }
    class Eq : Exp { Exp X, Y; }
    

    我在哈斯克尔怎么做?

    5 回复  |  直到 14 年前
        1
  •  6
  •   ephemient    15 年前
    {-# LANGUAGE GADTs #-}
    
    data Exp a where
        Const :: Show a => a -> Exp a
        Eq :: Exp a -> Exp a -> Exp a
    

    如果要允许在的不同分支中使用不同的数据类型, Eq 也没关系。

    data Exp where
        Const :: Show a => a -> Exp
        Eq :: Exp -> Exp -> Exp
    
        2
  •  4
  •   Nathan Shively-Sanders    15 年前

    你可以这样说

    data (Show a) => Exp a = Const a | Eq (Exp a) (Exp a)
    

    但这几乎总是一个坏主意,因为它强制使用 Exp 提到show约束,即使它从未使用 Show 方法。相反,只将show约束放在与之相关的函数上。见 Real World Haskell 为了解释。

        3
  •  2
  •   Martijn    15 年前

    如果你想知道关于 Const 你能做到吗? show 为什么不把结果储存起来呢? String 而是构造函数中的值?例如:

    data Exp = Const String | Eq Exp Expr
    
    example = Eq (Const (show 0)) (Const (show ""))
    

    这与您的C版本非常相似。

        4
  •  1
  •   Dan    15 年前

    回答评论中的第二个问题, Eq (Const 0) (Const "") 无法使用您拥有的数据类型实现,因为 Exp Integer Exp String 不是同一类型。一个选择是做一些像

    data Exp = forall a . Show a => Const a | Eq Exp Exp
    

    这是否对你有好处取决于你打算用这个类型做什么。

    编辑:这需要如前所述启用语言扩展。

        5
  •  1
  •   Rafael S. Calsaverini    15 年前

    我将只声明您的数据类型为类型类的实例show:

    data Exp a = Const a | Eq (Exp a) (Exp a)
    
    instance (Show a) => Show (Exp a) where
        show (Const a) = show a
        show (Eq x y ) = "[ " ++ show x ++ " , " ++ show y ++ " ]"
    

    在ghci中加载时会发生什么,然后执行以下操作:

    *Main> let x = Eq (Const 1) (Eq (Const 2) (Const 3))
    *Main> x      
    [1 , [2 , 3] ]
    

    回答意见:

    你可以很容易地处理不同的类型。假设您想要解析数学表达式。例如,您可以具有以下结构:

    data Expr  = Var String | Sum (Expr) (Expr) | Number Int | Prod (Expr) (Expr)
    

    这足以表示由数字和命名变量的和、积构成的任何表达式。例如:

    x = Sum (Var "x") (Prod (Number 5) (Var "y")) 
    

    表示:x+5y

    要把它印得漂亮,我会这样做:

    instance Show Expr where
        show (Var s) = show s
        show (Sum x y) = (show x) ++ " + " (show y)
        show (Prod x y) = (Show x) ++ (show y)
        show (Number x) = show x
    

    这就行了。您也可以使用小工具:

     data Expr where
          Var :: String -> Expr
          Sum :: Expr -> Expr -> Expr
    

    等。。。然后将其实例化为show。

    推荐文章