哈斯克尔问题:制约数据类型使用秀
-
13-09-2019 - |
题
代码:
data Exp a = Const a | Eq (Exp a) (Exp a)
我想要的 CONST一个包含的节目类型的值,这样我可以稍后打印。因此,在C#我会写:
class Const : Exp { IShow X; }
class Eq : Exp { Exp X, Y; }
我如何能做到这一点在Haskell?
解决方案
{-# 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
其他提示
您可以这样做。
data (Show a) => Exp a = Const a | Eq (Exp a) (Exp a)
但是,这是几乎总是一个坏主意,因为它会强制使用Exp
提秀约束,即使从来没有使用Show
方法每一个功能。相反,把展会的约束上只是它的相关的职能。请参见真实世界哈斯克尔一>一个解释。
如果你想知道即将Const
的说法是,你可以show
它,为什么不直接存储在构造函数,而不是导致String
价值?例如:
data Exp = Const String | Eq Exp Expr
example = Eq (Const (show 0)) (Const (show ""))
这非常类似于你的C#版本。
要回答第二个问题,在评论中问道,Eq (Const 0) (Const "")
是不是和你有数据类型实现的,因为Exp Integer
和Exp String
是不是同一类型。一种选择是像做
data Exp = forall a . Show a => Const a | Eq Exp Exp
至于这是否会做你任何好处取决于你打算使用的类型做什么。
编辑:这确实需要语言扩展如所提到的,以使能
。我只想宣布你的数据类型的类型类展会的一个实例:
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
这会做的伎俩。你也可以使用GADTs:
data Expr where
Var :: String -> Expr
Sum :: Expr -> Expr -> Expr
等...然后实例此作为显示。
不隶属于 StackOverflow