異なる型コンストラクターで同じ名前のデータコンストラクターが許可されないのはなぜですか?


11

次の宣言はエラーになります。

type Vec2d = (Float, Float)
type Vec3d = (Float, Float, Float)
-- Rect x y defines a rectangle spanning from (0,0) to (x,y)
data Obj2d = Rect Float Float
           | Translate Vec2d Obj2d
-- Cuboid x y z defines a cuboid spanning from (0,0,0) to (x,y,z)
data Obj3d = Cuboid Float Float Float
           | Translate Vec3d Obj3d

つまりMultiple declarations of 'Translate'

さて、なぜこの制限が導入されたのでしょうか?

制限がなければ、次のように書くことができます

Translate (1, 1) Rect 2 2 そして Translate (1, 2, 3) Cuboid 1 1 1、それは自然に聞こえます。

これがどのようにして同じ名前の使用を許可しないという入札の解析問題につながる可能性があるのか​​は(すぐには)わかりません。型は引数によって推測できます(Rect 2 2is Obj2dCuboid 1 1 1is、Obj3d)。

言語設計者が異なるタイプのデータコンストラクターに同じ名前を使用することを許可しないことを選択した正当な理由があると確信していますが、私は知りたいです:なぜ、それが明らかに必要ではないのですか?

(そして型の曖昧性解消はHaskellの基本的なビジネスです!)


3
引数によって推論される型について:引数の型が関数の型から推論されることを知っていますか?

@delnan知らなかった...私には答えのように聞こえる。私は常に推論がボトムアップであると考えていましたが、決定要因として説明したタイプグラフの反対側からのタイプ情報を使用して曖昧性の解決を見ることができました...これの私の精神的なイメージは、グラフと関数呼び出しが上部にある場合、解像度は下部から折りたたむことによって形成された集合体ですが、それは完全な全体像ではありません。当然のことながら、完全に推論された依存型付き言語では、これはおそらくより正確です。–
Jimmy Hoffa

回答:


13

これは、データコンストラクターが単なる関数であり、Haskellでは関数のオーバーロードが許可されていないためです。タイプを定義するためにGADT構文を使用すると、より明確になる場合があります。

{-# LANGUAGE GADTs #-}
data Obj2d where
    Rect :: Float -> Float -> Obj2d   -- a function from floats to obj2d's
    Translate :: Vec2d -> Obj2d       -- a function from vec2d's to Obj2d's

彼ら(GHC開発者)はtype class、同じデータコンストラクターまたは類似のものを共有するすべての型に新しいものを導入することを含む、この問題の可能な解決策に取り組んでいると思います。しばらくお待ちください。問題の解決策がまもなく提供される可能性があります。(私は願います)


type classあなたが規定しているこれらの構成要素を私は間違いなく楽しみにしています。-その理由は次のとおりです。私は問題を持っていない、私が行うことができますTranslate2Translate3d、私はむしろ、名前空間を汚染しないと思います。
A Sz

私はGHCの開発者ではないので、それはただの噂です。私もそれが起こることを望みます。
bstamour 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.