HaskellでEnumのサブクラスにバインドされないのはなぜですか


9

Boundedインスタンスには、Enumの適切な実装が必要なようです。私は反例を個人的に考えることはできませんが、誰かが病的でないものを思いついた場合、私はこれがそうでない理由を理解します。

:i2つのタイプクラスを実行することから、現在標準ライブラリにある唯一の例外はタプルの場合のようです。これは、バインドされているが列挙型ではありません。ただし、すべてのBoundedタプルは、最後の要素をインクリメントし、maxBoundに到達したときにラップすることによって、まともな方法でEnumerableにする必要もあります。

この変更には、Enum値をトラバースするための安全な/ループ方法のために、Boundedへの追加predBnextBそのようなものが含まれる可能性があります。この場合toEnum 0 :: (...)(toEnum 0, toEnum 0, ...) :: (...)


3
これについては正式に答えることはできませんが、0から1までのすべての実数の範囲を考慮してください。明確な下限と上限がありますが、メンバーは数え切れないほど無限です。
Doval

公正なポイントである@Doval。しかし、同じことが(非可算無限のメンバー)一般的にはすべての実数について語ったことができますが、Double/ Floatおよびすべての類似したタイプが実装Enumとにかく、彼らはただ作るsucc = (+ 1)fromEnum = truncate。Haskellの方法は実際にはそうでない場合と同様に実用性の観点から意味があり[0、0.5 ..]と同様に機能しないため、HanumはEnumに関しては可算性について心配していません。
セミコロン2016年

1
私は知らなかったsuccです(+1)。ので、それは、奇妙だDoubleFloat無限の精度を持っているので、いないです -可算succ1になるように定義されていたかもしれないULP
Doval 2016年

2
@Dovalその理由は、Haskellコアチームが[1 ..]をDoublesでもIntと同じ意味にしたかったからだと思います。
セミコロン2016年

@semicolonのdoubleとfloatは実数ではないため(たとえば、ある程度の精度を失うことなくPIをdoubleに格納することはできません)、列挙可能です
jk。

回答:


8

私が好きな実用的な例の1つは、プログラミング言語の世界にあります。OOシステムの型のセットは、限定的で離散的ですが列挙可能ではなく、部分的に順序付けされていますが、完全に順序付けされていません。

問題の部分的な順序はサブタイプの関係<:です。上限は(C#呼び出しとScalaが呼び出す)上部の型で、下限は下部の型(Scalaの; C#/ Javaには同等の機能がありません)になります。objectAnyNothing

ただし、型システムのすべての型を列挙する方法はないため、を作成することはできませんinstance Enum Type。これは明確である必要があります。ユーザーは独自の型を作成できるため、事前に自分が何になるかを知る方法はありません。特定のプログラムのすべてのタイプを列挙できますが、システム全体では列挙できません。

同様に、(サブタイプの特定の合理的な定義によると)<:は、再帰的、推移的、反対称的ですが、全体ではありません。とは無関係なタイプのペアがあります<:。(CatおよびDogは両方とものサブタイプですAnimalが、どちらも他方のサブタイプではありません。)


単純なオブジェクト指向言語用のコンパイラーを書いているとしましょう。システムでの型の表現は次のとおりです。

data Type = Bottom | Class { name :: String, parent :: Type } | Top

そして、サブタイピング関係の定義:

(<:) :: Type -> Type -> Bool
Bottom <: _ = True
Class _ _ <: Bottom = False
Class n t <: s@(Class m _)
    | n == m = True  -- you can't have different classes with the same name in this hypothetical language
    | otherwise = t <: s  -- try to find s in the parents of this class
Class _ _ <: Top = True
Top <: Top = True
Top <: _ = False

これにより、スーパータイピング関係も得られます。

(>:) :: Type -> Type -> Bool
t >: s = s <: t

また、2つのタイプの最小上限を見つけることもできます。

lub :: Type -> Type -> Type
lub Bottom s = s
lub t Bottom = t
lub t@(Class _ p) s@(Class _ q) =
    | t >: s = t
    | t <: s = s
    | p >: s = p
    | t <: q = q
    | otherwise = lub p q
lub Top _ = Top
lub _ Top = Top

演習:ショーというType形式囲まれた完全なposet下の二つの方法、<:および下>:


素晴らしいです、ありがとう!それは私の質問に完全に答え、Ordに関する私のフォローアップの質問にも答えます。Eqにも同様の問題がありますか?等しくないタイプには、maxBoundまたはminBoundがある場合があります。この場合、Cat == Dogは異なるクラスであるため、単にfalseを返す必要がありますか、それともツリーの位置が他の上下に配置されていないため、決定できませんか?
セミコロン

順序付けは同等であることを意味しますx == y = x <= y && y <= x。定義するだけです。もし私がPosetクラスをデザインしていたら、私はそうなるでしょうclass Eq a => Poset a。手っ取り早いグーグルは他の人々が同じ考えを持っていたことを確認します。
Benjamin Hodgson 2016年

すみません、私の質問があいまいでした。私が意味したのは、Ordを意味していなくても、BoundedがEqを意味しているかどうかです。
セミコロン

@semicolonここでも、2つのクラスの間に関係はありません。考えてみましょdata Bound a = Min | Val a | Max種類を強化しているa+∞し、-∞要素。建設することによりBound a、常にのインスタンスを行うことができるBoundedが、根本的なタイプがいる場合にのみequatableだろうaです
ベンジャミン・ホジソン

申し分なく十分です。私は1つの例が取る機能とタイプの戻り値であることができると思いますDoubleconst (1/0)ありmaxBoundconst (negate 1/0)あるminBoundが、\x -> 1 - xおよび\x -> x - 1比類のないです。
セミコロン

4

これは、操作が独立しているため、サブクラスの関係でそれらを結び付けても実際には何も購入しないためです。あなたが実装されたカスタムタイプを作成したいと言うBounded、おそらく、Doubles最大と最小の間に制約がありますが、任意のためには必要ありませんでしたEnum動作を制御します。Boundedサブクラスの場合は、Enumとにかくすべてをコンパイルしてコンパイルするために、すべての関数を実装する必要があります。

の適切な実装Enumやその他の数の型クラスがあるかどうかは問題ではありません。実際にそれが必要ない場合は、強制的に実装する必要はありません。

発言とは対照的、OrdおよびEq。そこではOrd操作が操作に依存してEqいるので、重複を避けて一貫性を確保するためにサブクラスを要求することは理にかなっています。


1
それらの場合、それは定義の一部です。すべてのモナドは、定義上、適用およびファンクタでもあるため、他のモナドを満たさずにモナドの「契約」を行うことはできません。それが基本的な関係なのか、強制された定義なのかを知るには、数学にはあまり詳しくありませんが、どちらにしても、今はそれを使い続けています。
カールビーレフェルト

6
@semicolonのドキュメントでBoundedは、「OrdはBoundedのスーパークラスではありません。完全に順序付けられていない型には上限と下限がある場合があるためです。」
Benjamin Hodgson 2016年

1
@BenjaminHodgson部分的に順序付けられた型についてさえ考えなかった。病理学的でない例とドキュメントを引用する場合は+1。
Doval

1
@semicolonコンピュータの世界からの部分的な順序付けの例は、OO言語でのサブタイピングです。<:forの書き込みはのサブタイプであり∀ T S. T <: S ∨ S <: T保持されません(例:)int !<: bool ∧ bool !<: int。コンパイラーを作成している場合は、おそらくこれに遭遇するでしょう。
Benjamin Hodgson

1
@BenjaminHodgsonあ、大丈夫。たとえば、AがBとCのスーパークラスであり、DがBとCのサブクラスである場合、BとCは比較できませんが、AとDは最大/最小ですか?
セミコロン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.