In haskell without lenses I can do things like :
data Item = Item { quantity :: Double, price ::Double }
cost :: Item -> Double
cost = (*) <$> quantity <*> price
If I use lenses instead how can I do the equivalent ? The best I can do is
cost = to $ (*) <$> (^. quantity) <*> (^. price)
Is there a better way ? (of course I want a getter
or equivalent)
It just occurred to me that you don't need any special syntax to combine lenses. If you are creating lenses using Template Haskell (which you should be doing) then you already have primitive getters for each field, preceded by an underscore.
Hence, you could use the primitive getters to create your phantom cost
getter as follows:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data Item = Item { _quantity :: Double
, _price :: Double
}
$(makeLenses ''Item)
cost :: Getter Item Double
cost = to $ (*) <$> _quantity <*> _price
item :: Item
item = Item { _quantity = 2, _price = 5.0 }
main :: IO ()
main = print $ view cost item
However, if you don't have access to the primitive getters then you could define cost
as:
cost :: Getter Item Double
cost = to $ (*) <$> view quantity <*> view price
Your fingers don't need to move too far away from the home row in order to type out view
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With