data Ray = Ray Vector Vector
また
type Ray = (Vector, Vector)
慣用的なhaskellではどちらが好ましいですか?なぜ一方を他方の上に使用する必要があるのですか?
パフォーマンスは気にしません。
関数とはほとんど違いがないようです。例:
trace :: Ray -> …
trace (Ray x d) = …
-- OR
trace (x, d) = …
バージョンは、プログラマーの意図をより明確に示すため、優先されます。data
新しい型を作成することにより、これが単なるタプルではなく、意味のあるセマンティック エンティティである a Ray
.
これにより、型システムにさらに依存することが可能になり、 のカスタム インスタンスとRay
、タプルでは不可能な最適化が可能になります。
2 つの組み合わせのような 3 番目のオプションを検討することもできます。newtype
newtype Ray = Ray (Vector, Vector)
私の意見では、代数データ型は、複数の選択肢がある場合、または型を再帰的にしてそれ自体を含める必要がある場合に使用されます。しかし、このようなものにはやり過ぎかもしれません。
Don Stewart は、型をタプルと同義にすることは、そのタプル型を直接使用することと同じであると指摘しました。型シノニムには独自のアイデンティティがありません。そのため、型チェッカーは型とタプルを区別できず、必要な場所で型を使用していることを確認できません。また、タプルとまったく同じインスタンスを持つことになります。
Anewtype
を使用すると、タプルと同じ基になる型を使用できます。ただし、型チェッカーとは別の型であり、別のインスタンスがあります。
私が非常に便利だと思った 4 番目の選択肢は、次のレコードです。
data Ray = Ray { from, to :: Vector }
それらは基本的に「通常の」ADT のすべての機能を備えていますが、いくつかの構文糖衣が追加されています。特に、部分的に変更された値のコピーを簡単に取得できます。状況によってはレコードが制限されすぎていることは事実ですが、その場合はfclabelsのような「改善されたバージョン」でさらに進めることができます。