我有几个数据结构,比如
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
在传递时成为这两种类型的无操作Nothing
。
这可以使用现有的组合器还是我必须自己编写镜头?我这样做很好,但是大多数现有教程都使用 TH 并掩盖了手工编写的细节。
我正在使用 GHC 7.6.3 和lens
3.10。