11

fstとがあることは知っていますがsnd、型クラスを使用するそのようなアクセサ関数の「一般的な」定義がないのはなぜですか? 私は次のようなものを提案します

class Get1 p a | p -> a where
  get1 :: p -> a 

instance Get1 (a,b) a where
  get1 (x,_) = x 

instance Get1 (a,b,c) a where
  get1 (x,_,_) = x 

class Get2 p a | p -> a where
  get2 :: p -> a 

instance Get2 (a,b) b where
  get2 (_,x) = x 

instance Get2 (a,b,c) b where
  get2 (_,x,_) = x 

確かに、これにはいくつかの言語拡張が必要ですが、これはその方がはるかに便利ではありませんか? 特に、独自のタイプのインスタンスを追加できます。

4

2 に答える 2

7

注意すべきことの 1 つは、2 タプルを表示できるのは 1 つだけでfstあることです。sndそれらを他のアリティや操作に一般化することは、すぐに苦痛になります。たとえば、タプルの最初の要素にもマップしたい場合は、別のコンビネータを導入する必要があります (これは、2 タプルに対して として存在しますControl.Arrow.first)。これにより、アリティの高いタプルのコンビネータの数が爆発的に増加します。

そうは言っても、lensタプルを操作するための優れたツールがいくつか提供されています。アリティ 9 までのタプルの 1 番目、2 番目などの要素へのアクセスを許可Control.Lens.Tupleするいくつかのインデックス レンズ_1、などを提供します。_2

例えば、

>>> import Control.Lens
>>> let t = (1,2,3,5,6,7,2)
>>> t ^._1
1
>>> t & _1 .~ 'a'
('a',2,3,5,6,7,2)
>>> t & _1 +~ 41
(42,2,3,5,6,7,2)
>>> over _1 (+1) t
(2,2,3,5,6,7,2)

のタプル インスタンスにも興味があるかもしれませんControl.Lens.At。また、このtuple-lenses パッケージは、複数のタプル エントリを一度に調べるための、より一般的なレンズをいくつか提供します。

于 2013-03-12T12:28:28.127 に答える
3

このような型クラスは、コーディング (構文) の利便性のみを提供します。タプル型ツールを一般化して構築する方法がわかりません。タプルの一般化を探している場合は、Redditの異種ベクトルに関する議論を確認してください。

また、通常の構造体の場合は、独自の ADT を定義し、getter にわかりやすい名前を付けてから、アリティの高いタプルを使用することが望ましいことに注意してください。

編集:ただし、コメントでis7sが指摘しているように、任意の長さのタプルのインデックス作成機能を提供するハックのパッケージがいくつかあります。

于 2013-03-12T10:14:58.993 に答える