{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data Fruit = Fruit
{ _fruitColor :: String
}
$(makeClassy ''Fruit)
data Fruits =
Banana Int Fruit
| Strawberry String Fruit
printer :: HasFruit s => s -> IO ()
printer f = putStrLn $ f ^. fruitColor
sample :: IO ()
sample = do
printer $ Fruit "yellow"
printer $ Banana 5 $ Fruit "yellow"
我有一个核心产品类型,Fruit。我希望数据类型都包含核心产品类型Fruit,但希望能够用sum类型Fruit表示它们。使用和类型Fruits,我希望能够访问核心产品类型Fruit的组件。也就是说,我喜欢像香蕉和草莓这样的类型是HasFruit的一个例子。
有没有直接的方法让Fruits实例化HasFruit?是否有更好的模式来表示这一点 - 总和类型的核心产品类型?
答案 0 :(得分:1)
做这样的事情会更有意义:
data FruitType = Banana Int | Strawberry String
data Fruits = Fruits { _fruitsFruitType :: FruitType, _fruitsFruit :: Fruit }
makeFields ''Fruits
-- `Fruits` now instantiates `HasFruit`
您可能还想为FruitType
制作棱镜。棱镜基本上是遍历总和类型的不同部分,除了它们也可用于构造它。
makePrisms ''FruitType
-- double the int if the argument is a `Banana`
doubleBanana = fruitType._Banana *~ 2