次のようないくつかのデータ構造があります
data Data1 = Data1
{ _data1Field :: Int
-- More fields
} deriving (Eq, Show)
makeLenses ''Data1
data Data2 = Data2
{ _data2Field :: Int
-- More fields
} deriving (Eq, Show)
makeLenses ''Data2
-- More similar data types
そこで、簡単に作成できるように単純な型クラスを作成することにしました
class HasField a where
field :: Lens' a Int
instance HasField Data1 where
field = data1Field
instance HasField Data2 where
field = data2Field
しかし、これらの構造の一部に対応するフィールドがオプションとしてあるという問題に遭遇しました
data Data3 = Data3
{ _data3Field :: Maybe Int
-- More fields
} deriving (Eq, Show)
makeLenses ''Data3
そして今、型クラスを使用できなくなりました。そのフィールドがオプションではないデータ型とほぼ同じ数のデータ型があるため、型クラスを変更する方がよいと判断しました。
class HasField a where
field :: Lens' a (Maybe Int)
instance HasField Data3 where
field = data3Field
しかし、私はレンズ ライブラリの経験があまりないので、この新しいレンズをData1
およびの型で機能させる方法を考え出すのに苦労していますData2
。理想的には、それを表示してMaybe Int
任意のタイプの値を取得できるようにしたいと思います。設定するときJust x
は、フィールドをx
forData1
とに設定しData2
、渡されたときにこれら 2 つのタイプの操作を行わないようにしたいと考えていNothing
ます。
これは既存のコンビネータを使用して可能ですか、それとも自分でレンズを作成する必要がありますか? 私はそうしても問題ありませんが、既存のチュートリアルの大半は TH を使用しており、手書きでの記述の詳細については触れていません。
GHC 7.6.3 とlens
3.10 を使用しています。