質問
そして二つのデータ型Foo、Barです。Foo分野ではxとy.バー分野でのx、z.こういうことができるように関数を書くのとはFooまたはバーとしてのパラメータを抽出し、x値を一定の計算式で返しまの新しいFooバーのx値の選定にあたっております。
こちらにはアプローチ:
class HasX a where
getX :: a -> Int
setX :: a -> Int -> a
data Foo = Foo Int Int deriving Show
instance HasX Foo where
getX (Foo x _) = x
setX (Foo _ y) val = Foo val y
getY (Foo _ z) = z
setY (Foo x _) val = Foo x val
data Bar = Bar Int Int deriving Show
instance HasX Bar where
getX (Bar x _) = x
setX (Bar _ z) val = Bar val z
getZ (Bar _ z) = z
setZ (Bar x _) val = Bar x val
modifyX :: (HasX a) => a -> a
modifyX hasX = setX hasX $ getX hasX + 5
問題は、すべてのsetterか、セッターなど痛みを伴う、特に交換すれば、FooとBarと実世界データの種類の多い。
ウルド構文、素晴らしい方法を定義するこれらの記録です。でも、もし私の記録をこのような
data Foo = Foo {x :: Int, y :: Int} deriving Show
data Bar = Foo {x :: Int, z :: Int} deriving Show
ないエラーとxが定義されます。やさいを見せるこのタイプのクラスでできたらいいのにしていmodifyX.
ある素敵なクリーンの問題解決のための、amにこだわった定義することを自分のsetterか、セッター?別の言い方をすれば、はしてもらえると助かりますので接続機能を作成した記録の書式とタイプクラスのsetterか、セッター)?
編集
この問題のようにしている問題もあります。私書シリーズの関連プログラム利用システム。ソフトである。GetOptを解析してそのコマンドラインオプションがたくさん出てしまうと思いますコマンドラインオプションについてこれらのプログラムが、一部のプログラムに追加します。私は各プログラムを指定することができ、記録を含むすべてのオプション値です。私はそのデフォルトの記録値とその変容を通じてStateT monadとGetOptを最終的に記録を反映したコマンドライン引数になります。単一のプログラムは、このアプローチは適切に働きんもんへの再利用コードの全てのプログラム.
他のヒント
あなたのようなコードを使用することができます。
data Foo = Foo { fooX :: Int, fooY :: Int } deriving (Show)
data Bar = Bar { barX :: Int, barZ :: Int } deriving (Show)
instance HasX Foo where
getX = fooX
setX r x' = r { fooX = x' }
instance HasX Bar where
getX = barX
setX r x' = r { barX = x' }
あなたのコードで何をモデル化していますか?我々は問題の詳細を知っていたならば、我々は関数型言語にshoehornedこのオブジェクト指向設計よりも少ない厄介な何かを示唆することができます。
ジェネリック医薬品のための仕事のように私には思えます。あなたが別のnewtypesであなたのIntにタグを付けることができれば、あなたは(ユニプレート、モジュールPlateDataで)書くことができるようになります:
data Foo = Foo Something Another deriving (Data,Typeable)
data Bar = Bar Another Thing deriving (Data, Typerable)
data Opts = F Foo | B Bar
newtype Something = S Int
newtype Another = A Int
newtype Thing = T Int
getAnothers opts = [ x | A x <- universeBi opts ]
これはどこでも付き合え内部からすべての別のを抽出します。
変更も可能である。
あなたはあなたのアクセサの基礎として使用することができますToListメソッドの機能を取得します。
折り畳み式はあなたのものでない場合は、、そして多分正しいアプローチは、型クラスとしてしたいインターフェイスを定義し、得られた値を自動生成するための良い方法を把握することです。
おそらくやってから派生させます。
deriving(Data)
あなたのアクセスをオフベースにGMAPコンビネータを使用することができます。