使用具有多个数据构造函数的相同镜头
Use the same lens with multiple data constructors
假设我有这样的类型:
data Stock = Stock {
_stockSymbol :: String,
_stockFairValue :: Float,
_stockBuyAt :: Float,
_stockCurrentPrice :: Float
} |
Etf {
_etfSymbol :: String,
_etfFairValue :: Float,
_etfBuyAt :: Float,
_etfCurrentPrice :: Float
} deriving (Eq)
Stock
和 Etf
都有相同的字段。现在我想访问其中之一的符号:
item ^. symbol -- don't care if stock or etf
我可以用类型类做到这一点,但我想知道镜头包是否可以自动为我构建这个镜头?我看过 makeFields
函数,但如果我单独定义构造函数,它似乎可以工作:
data Stock = Stock { ... }
data Etf = Etf { ... }
有什么方法可以做到这一点,同时让它们保持在同一类型下吗?
编辑:有效:
makeLensesFor [("_stockSymbol", "symbol"),
("_etfSymbol", "symbol"),
("_stockFairValue", "fairValue"),
("_etfFairValue", "fairValue"),
("_stockBuyAt", "buyAt"),
("_etfBuyAt", "buyAt"),
("_stockCurrentPrice", "currentPrice"),
("_etfCurrentPrice", "currentPrice")
] ''Stock
不确定是否有内置的方式让我不必写出字段。
不是不同意 bheklilr 的评论,但你可以这样做:
data Stock =
Stock {
_symbol :: String,
_fairValue :: Float,
_buyAt :: Float,
_currentPrice :: Float
} |
Etf {
_symbol :: String,
_fairValue :: Float,
_buyAt :: Float,
_currentPrice :: Float
} deriving (Eq)
$(makeLenses ''Stock)
假设我有这样的类型:
data Stock = Stock {
_stockSymbol :: String,
_stockFairValue :: Float,
_stockBuyAt :: Float,
_stockCurrentPrice :: Float
} |
Etf {
_etfSymbol :: String,
_etfFairValue :: Float,
_etfBuyAt :: Float,
_etfCurrentPrice :: Float
} deriving (Eq)
Stock
和 Etf
都有相同的字段。现在我想访问其中之一的符号:
item ^. symbol -- don't care if stock or etf
我可以用类型类做到这一点,但我想知道镜头包是否可以自动为我构建这个镜头?我看过 makeFields
函数,但如果我单独定义构造函数,它似乎可以工作:
data Stock = Stock { ... }
data Etf = Etf { ... }
有什么方法可以做到这一点,同时让它们保持在同一类型下吗?
编辑:有效:
makeLensesFor [("_stockSymbol", "symbol"),
("_etfSymbol", "symbol"),
("_stockFairValue", "fairValue"),
("_etfFairValue", "fairValue"),
("_stockBuyAt", "buyAt"),
("_etfBuyAt", "buyAt"),
("_stockCurrentPrice", "currentPrice"),
("_etfCurrentPrice", "currentPrice")
] ''Stock
不确定是否有内置的方式让我不必写出字段。
不是不同意 bheklilr 的评论,但你可以这样做:
data Stock =
Stock {
_symbol :: String,
_fairValue :: Float,
_buyAt :: Float,
_currentPrice :: Float
} |
Etf {
_symbol :: String,
_fairValue :: Float,
_buyAt :: Float,
_currentPrice :: Float
} deriving (Eq)
$(makeLenses ''Stock)