3

コード:

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

Const aに show 型の値を含めて、後で印刷できるようにします。したがって、C#では次のように記述します。

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

Haskellでそれを行うにはどうすればよいですか?

4

5 に答える 5

6
{-# 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
于 2009-12-07T01:40:21.363 に答える
4

あなたは言うことによってこれを行うことができます

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

しかし、メソッドExpをまったく使用しない場合でも、使用するすべての関数が show 制約に言及することを強制するため、これはほとんど常に悪い考えです。Show代わりに、関連する関数だけに show 制約を設定してください。説明については、 Real World Haskellを参照してください。

于 2009-12-07T01:00:55.753 に答える
2

の引数について知りたいのConstは、それができるということだけである場合は、代わりに結果の値をコンストラクターにshow格納してみませんか? String例えば:

data Exp = Const String | Eq Exp Expr

example = Eq (Const (show 0)) (Const (show ""))

これは、C# のバージョンとよく似ています。

于 2009-12-07T22:20:01.707 に答える
1

私はあなたのデータ型を型クラス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

これでうまくいくでしょう。GADTを使用することもできます。

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

など...そしてこれをShowとしてインスタンス化します。

于 2009-12-09T15:05:18.463 に答える
1

コメントで尋ねられた2番目の質問に答えるには、とが同じタイプではないため、Eq (Const 0) (Const "")あなたが持っているデータ型では達成できません。1つのオプションは、次のようなことをすることですExp IntegerExp String

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

それがあなたに役立つかどうかは、そのタイプで何をしようとしているかによって異なります。

編集:これには、前述のように言語拡張機能を有効にする必要があります。

于 2009-12-07T20:38:41.997 に答える