假设我有一个这样的类型:
有没有办法在保持它们为同一类型的情况下完成此操作?
编辑:这个可行:
data Stock = Stock {
_stockSymbol :: String,
_stockFairValue :: Float,
_stockBuyAt :: Float,
_stockCurrentPrice :: Float
} |
Etf {
_etfSymbol :: String,
_etfFairValue :: Float,
_etfBuyAt :: Float,
_etfCurrentPrice :: Float
} deriving (Eq)
股票
和 ETF
都有相同的字段。现在我想访问其中一个的符号:
item ^. symbol -- don't care if stock or etf
我可以使用类型类来完成这个任务,但我想知道是否有lens包可以自动为我构建此镜头?我已经查看了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
我不确定是否有内置的方法,可以避免手动书写字段。
Stock { isEtf :: Bool, _stockSymbol :: String, ... }
。如果所有字段都相同,唯一的区别是构造函数,那么只需将构造函数作为字段即可。我猜测 lens 库不支持你尝试做的事情,因为多构造函数记录通常不被鼓励。 你可以尝试在两个构造函数中使用相同的字段名称,这可能会起作用。 - bheklilr_etfBuyAt (Stock "" 0 0 0)
,那会怎样呢?引入部分函数会降低安全性,这可能导致应用程序崩溃。 - bheklilrStock
和Etf
,但由于镜头,我可以在两者上使用相同的函数。如何编写一个可以接受任一一个类型的函数呢?就像getSymbol :: EitherStockOrEtf -> String
。 - Vlad the Impalalens
实际上可以减少多构造函数记录的问题,因为它确保仅在字段未始终定义时才派生Traversal
。 - Ørjan Johansen