2017-05-01 16 views
1

this を読んでしまったと私は、コードのいくつかの部分は何をすべきかを把握しようとしています。メソッドシグネチャHaskellのユーザー定義型

infixl 4 :+: 
infixl 5 :*:, :/: 
infixr 6 :^: 

data Expr a = Var Char 
      | Const a 
      | (Expr a) :+: (Expr a) 
      | (Expr a) :*: (Expr a) 
      | (Expr a) :^: (Expr a) 
      | (Expr a) :/: (Expr a) 
      deriving (Show, Eq) 

と、次の機能があります::

まず

は、データ型定義があります

simplify :: (Num a, Eq a, Floating a) => Expr a -> Expr a 
simplify (Const a :+: Const b) = Const (a + b) 
simplify (a  :+: Const 0) = simplify a 
simplify (Const 0 :+: a  ) = simplify a 

だから、「何(NUM、式、フローティング)= > Expr a "はこの場合のためのものですか?

"Expr"はコンストラクタではなく、最初の行では "+(Expr Expr)"なので、ここでは "a"は何を意味し、なぜ2倍に制限されていますか? そして、「」「」機能の2行目では、ここでもあれば、明らかExprにある?に関連する型シグネチャでありますか型クラスNumEqFloatingためのインスタンスがある各タイプaについて

+1

「+(Expr Expr)」はどこにもありません。何を参考にしていますか? BTW、 'Expr a'は、コンストラクタが' Var、Const、(:+ :)、(:* :)、(:^ :)、(:/ :) 'の型です。表記 – chi

+0

理解に役立ついくつかの用語: 'Expr'は、*型変数* aから型を構築するため、*型のコンストラクタです。 'Expr'は通常の1種類のデータ型(' * ')を取り、別の通常のデータ型(' * ')を返すため、* kind *' * - * * 'を持ちます。 'Var'、' Const'、 ':+:'などは引数が何であっても 'Expr a'sを構築するので、*データコンストラクタです。 'Var :: Char - > Expr a'、' Const :: a Expr a'、 '(:+ :) :: Expr a - > Expr a - > Expr a'などに注意してください。 – Lazersmoke

答えて

1

simplifyExpr a -> Expr aに特化することができます。型と値の名前空間は別々です。 Exprは型コンストラクタです。 Expr aは値を持つ型です。ここでは何もDoubleに制限されていない、(+)Numインスタンスですべてを認めています。

3
データ定義で

data Expr a = ... 

a型変数が存在することを意味します。簡単な例としては、これは、単一の型パラメータを取る名前Two、持つタイプである

data Two a = Two a a 

だろう。また、2つのフィールドを有するTwo、タイプaのそれぞれと呼ばれるデータコンストラクタを有します。例えば、タイプTwo Intは、この場合の特殊なコンストラクタTwo :: Int -> Int -> Two Int

を持って、あなたはタイプaのフィールドを持っているそのうちのいくつかは、あなたのExpr型は型パラメータを持っていることを言って、およびコンストラクタの数を持っています。あなたは、このようなConst 1 :+: Const 2として、タイプExpr Intの価値を持っているために、これを使用する場合があります。

あなたは

simplify :: (Num a, Eq a, Floating a) => Expr a -> Expr a 

のようなタイプの署名を参照すると、この関数はタイプExpr aの値を取り、型変数aは追加の制約があり、ここを除いて、同じ型の値を返すことを意味します。即ち、Num,Eq,Floatingである。これらは型クラスであり、あなたがExpr asimplifyを使用できるようにするためにタイプaは、これらの型クラスを実装する必要があります。

タイプシグニチャのaは、simplifyの定義の最初の行のaとは関係ありません。これは、著者が同じ名前を使用するという選択肢に過ぎません。型名とデータ名は、Haskellのまったく異なる名前空間にあり、矛盾や関連はありません。

関連する問題