合計型-Haskellで `show(Int | Double)`が `(show Int)|と異なる理由 (ダブルを表示) `


9

なぜこれらは同等ではないのですか?

show $ if someCondition then someInt else some double

そして

if someCondition then show someInt else show someDouble

if ... else最初の例の部分を単独で式に分離した場合Int | Double、TypeScriptで簡単に実行できるようなTypeのような匿名合計型でその型を表すことができないことを理解しています(TypeScriptについて言及しているため、 langaugeは頻繁に使用し、Sum型をサポートしているため、Eitherデータを使用する必要があるため、それに基づいてを呼び出しますshow

ここで示した例はささいなことですが、私にとっては、someCondition「何かを表示し、何かが依存する」と考える方が理にかなっています。コードの重複が少ない場合(ここでは、ショーが2回繰り返されますが、長い関数のアプリケーションでif ... elseある可能性があり、2つ以上の分岐を検討する必要がある場合もあります)

私の考えでは、合計型(ここではInt | Double)を構成する各型がshow関数のパラメーターとして使用できるかどうかをコンパイラーがチェックし、型が正しいかどうかを判断するのは簡単です。さらに良いのは、show関数がstringパラメーターのタイプに関係なく常に返されるため、コンパイラーがすべての可能な「ブランチ」(したがってすべての可能なタイプ)を運ぶ必要がないことです。

そのような機能が存在しないのは選択によるものですか?それとも、実装するのは難しいと思いますか?


2
アンはif ... then ... else ...、内の同じタイプの持っている必要がありますthenし、else一部を。一部のプログラミング言語では、これを三項演算子として見ることができます。
Willem Van Onsem

1
に同意しmaking all conversions explicitます。私の質問では、HaskellをにキャストIntDoubleたり、その逆をしたりしたくありません。例として、この2つのタイプを使用しました。あなたはすべてを置き換えることができIntaDoubleしてb、両方のタイプが派生私の質問にShowanonymous sum typesHaskell にはないことを理解していますが、なぜそうなのか、そしてそれを実現するための言語の設計を妨げている理由を知りたいのです。
Mehdi Saffar

4
そのような型は共用体型と呼ばれていると思います。合計タイプは、基本的には共用体タイプのタグ付きバリアントであり、各値は内部タイプの値を超えて左/右タグを運ぶ必要があります。Haskellのすべての型レベルの機能を使用して、共用体型との型推論を実現することは非常に難しいと思います。x :: Int | Boolコンパイルする必要がある場合、型消去ベースのRTSで、show xを呼び出すために使用する関数へのポインターを簡単に知る方法はありませんshow。実行時にいくつかのタイプレベルの情報を保持する必要があるでしょう。
カイ

1
匿名の合計型を持たないことは、Haskellデザイナーの設計上の決定です。彼らがどのようなメリットをテーブルにもたらすかはよくわかりませんが、どこが複雑なのかはわかりません。ですから、私の推測では、費用対効果の比率がないために除外されていると思います。ただし、確実に元の言語デザイナーや現在のメンテナーに尋ねる必要があります。言語の設計には多くの個人的な意見や趣味が関わっているので、それがすばらしいSOの質問になるとは思いません。
n。「代名詞」m。

4
(String, Int)匿名ではありません。それはおかしな構文を持つ通常の製品タイプにすぎません。(String | Int)まったく違うでしょう。(Int|Int)と同一であるかどうかIntとその理由を自問することから始めます。
n。「代名詞」m。

回答:


8

式のすべての部分は、適切に入力する必要があります。のタイプはのif someCondition then someInt else someDoubleようなものである必要がありますがexists a. Show a => a、Haskellはそのような実存定量化をサポートしていません。

更新:chiがコメント指摘しているように、Haskellが和集合/積集合型(和/積型と同じではない)をサポートしている場合にも可能ですが、残念ながらそうではありません。


ユニオン/交差タイプと合計/積タイプの違いについて詳しく教えていただけますか?私はいつも、匿名性を除いて、それらは同じだと思っていましたか?
Mehdi Saffar

1
@MehdiSaffar名前のないコンストラクターではなく、タグなしのように匿名。つまり、がある場合Int ∪ Double、2つのうちの1つがあることはわかっていますが、パターンマッチでどちらを表示するかを判断できないため、両方の可能性に対して有効なことしか実行できません。
Joseph Sible-Reinstate Monica

2
明確にするために、TypeScriptには実行時に使用できる型情報typeofがあるため、タグ付けの欠如を補い、どの型が使用されているかを確認できる演算子があります。Haskellは完全に型消去されているので、この機能をサポートしていれば、それに相当するものはありません。
ジョセフSible-Reinstateモニカ

7

(,)Haskellには、軽量な構文で書かれた製品タイプがあります。のような軽量の構文を使用したsum型が(Int | String)優れたアイデアになるでしょう。現実はもっと複雑です。理由を見てみましょう(私はといくつかの自由を取ってNumいますが、それらは重要ではありません)。

if someCondition then 42 else "helloWorld"

これがのような型の値を返す必要がある場合(Int | String)、次に何を返す必要がありますか?

if someCondition then 42 else 0

(Int | Int)当然ですが、これが単純なものと異なる場合Intは、深刻な問題に直面しています。したがって(Int | Int)、plainと同じでなければなりませんInt

これは合計型の単なる構文ではなく、まったく新しい言語機能であることがすぐにわかります。可能であれば別の種類の型システム。持っておくべき?

この関数を見てみましょう。

mysteryType x a b = if x then a else b

今、どんなタイプがmysteryTypeありますか?明らかに

mysteryType :: Bool -> a -> b -> (a|b)

正しい?同じタイプの場合はどうaなりbますか?

let x = mysteryType True 42 0

Int以前に合意したとおり、これは明白なはずです。今、mysteryType時々匿名和型を返す、そして時にはそれが、に応じて、どのような引数あなたは渡しません。このような表現をどのようにパターンマッチングしますか?地球上で何ができるでしょうか?"show"(またはインスタンスとなる他のタイプクラスのメソッド)などの些細なことを除いて、全体ではありません。言語に実行時の型情報を追加しない限り、つまり、typeof利用可能であり、Haskellはまったく異なる言語になります。

そうそう。HaskellがTypeScriptでないのはなぜですか?別のTypeScriptは必要ないからです。TypeScriptが必要な場合は、どこにあるかわかっています。


1
@MichaWiedenmann率直に言って、「関連」が正しい言葉かどうかはわかりません。何らかの形で役立っていると思います。はい、私はちょっと立ち止まり、それを含めるかどうかを考えました。しかし、私は時々間違っていることが知られています。
n。「代名詞」m。

問題ありません、あなたの投稿です。
Micha Wiedenmann、

それであなたの代名詞は何ですか?
dfeuer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.