2016-06-14 16 views
1

私は次の値コンストラクタがあるとします。値コンストラクタで宣言された型がHaskell型でないのはなぜですか?

data Shape = Circle Float Float Float | Rectangle Float Float Float Float 

今、私は実行することができます:

ghci> :t Circle 
Circle :: Float -> Float -> Float -> Shape 

今、私は型宣言

surface :: Shape -> Float 

を書くことができます。しかし、私は入力できません型宣言

surface :: Circle -> Float 

このis becauseCircleがタイプではない、Shapeがある」

私の質問は次のとおりです。型は値コンストラクタではないHaskellの中の型で宣言されているのはなぜ?

+8

「値コンストラクタで宣言された型」である可能性があります。型ではないので、値のコンストラクタで宣言された型は間違いありません。彼らはデータコンストラクタです。また、 'surface :: 13 - > 1.2'という関数を書くこともできません。 – pdexter

+3

'data'の構文は歴史的な事故です。より一貫した方法でコンストラクタに型を渡すには、GADT構文を使用します。 – augustss

+0

@augustss ...実際には事故ではありません - 私はGADTsがまだ標準でさえない(それほど重要ではない) – Carsten

答えて

8
data Shape = Circle Float Float Float | Rectangle Float Float Float Float 

Shapeタイプ(および型コンストラクタ)です。 Floatが別のタイプです。

CircleおよびRectangleは、タイプShapeの値コンストラクタです。

あなたの混乱はOOPサブタイプ化から来ていると思います.Haskellにはそれに類似したものはありません。上記の2種類のCircleRectangleは、サブタイプがShapeであると宣言していません。あなたが実際に引数がCircleとして構築されてきたShape値であることを意味foo :: Circle -> Floatような何かを書くことができますGADTsのようないくつかの高度な機能拡張を使用して

。これにはいくつかのタイプレベルの技術が必要です。

また、プレーンHaskellのアプローチでは意味をなさない

data Circle = Circle Float Float Float 
data Rectangle = Rectangle Float Float Float Float 
data Shape = Scircle Circle | Srectangle Rectangle 
関連する問題