私はHaskellを学習しており、現在データメンバーのための「アクセサ」を発見しています。 のは、私はいくつかのダミー2D頂点情報、いくつかの色を持っている1種類、いくつかのテクスチャ座標を持っている以外の(TC)があると仮定してみましょう:存在しないレコードのHaskellアクセサリー
data SVertex = VertexC (Float, Float) Int
| VertexTC (Float, Float) (Float, Float)
deriving(Show)
一つの退屈な方法レコードをアクセサを作成するためには、パターンを持つ関数を書くことです:
position (VertexC (x,y) c) = (x,y)
position (VertexTC (x,y) c) = (x,y)
tc (VertexTC _ tc) = tc
color :: SVertex -> Int
color (VertexC _ c) = c
さて、正の機能は、私が「色」や「TC」を持っていないもののためにアクセサ(「色」と「TC」)を追加することができていることである:
position (VertexC (x,y) c) = (x,y)
position (VertexTC (x,y) c) = (x,y) -- no header, here... still works
tc (VertexTC _ tc) = tc
tc (VertexC _ _) = (0,0) -- to returns something even if the field doesn't exist
color :: SVertex -> Int
color (VertexC _ c) = c
color (VertexTC _ _) = 0 -- return something even if field doesn't exist
テクスチャ座標を持たない頂点、または色を持たない頂点に0のデフォルト値を与えることができます。 すべて良い...
今、私の質問私は現在、データ宣言にアクセサー名を付ける良い方法があると読んでいます。ここに私の場合は は、私は(名前の競合を避けるために、「プライム」を使用して)になるだろうです:「位置「」、「TC」」と「色:
data SVertex' = VertexC' {
position' :: (Float, Float),
color' :: Int
}
| VertexTC' {
position' :: (Float, Float),
tc' :: (Float, Float)
} deriving(Show)
これは私が同じ目標を達成することができます''アクセサが私のために作成されました!
:存在しないフィールドにデフォルトアクセサーを付ける方法が見つかりませんでした。たとえば、 'VertexC'でtcを要求するとき。またはVertexTCの色を要求しています... 最初のアプローチでは、私はそれを実現させることができます。この便利な第二のアプローチでは、私はそれが不可能であることを恐れている。 私は
color' (VertexTC' _ _) = 0
のような他の機能パターンを追加しようとすると、コンパイラは私に語っ「などの 『色』の複数の宣言」。そして、それは、この2番目の宣言がコンパイラによって作成された前の暗黙のものに続いて行われないためです。
回避策をご存知ですか?
私はこれが可能ではないと思います。Haskellのレコードは、一般的には苦労しています(特に、部分的であるという事実は、あなたが取得しているもののようなものです)。レコードに興味があるなら、おそらく、 '' lens''(https://hackage.haskell.org/package/lens)をある時点でチェックアウトすることになります(この部分的性は 'Prism'抽象化を使って扱われます) )。 – Alec
これは不可能ですが、非慣用的なHaskellの指標にもなります。グローバルルールを作るのではなく、 'SVertex'インスタンスを使ってこれらのデフォルトを扱うときに、パターンマッチングをより重視することを検討してください(後者のアプローチは非常にJava風です)。 –
私はHaskellで「レコード」にアクセスできないことに気付かなかった。どのように私はこのことに気づくべきであるかについての確認をありがとう。 この範囲で改善を図っている人もいるようです:http://nikita-volkov.github.io/record/ –