Reputation: 2472
I have the following program:
{-# LANGUAGE TemplateHaskell #-}
import qualified Data.Map.Strict as Map
import Control.Lens
data MyLabel = MyLabel { _label :: String } deriving (Show, Eq, Ord)
data MyMap = MyMap { _vals :: Map.Map String MyLabel } deriving (Show, Eq, Ord)
makeLenses ''MyLabel
makeLenses ''MyMap
sample :: MyMap
sample = MyMap { _vals = Map.fromList [("foo", MyLabel "bar")] }
Now I'd like to know how to do a transformation f
using lenses such that:
f sample "quux" == MyMap { _vals = Map.fromList [("foo", MyLabel "quux")] }
I learned that the function at
from Lens library should be used to modify Maps, so I was trying to do things like this:
sample ^. vals & at "foo" . label .~ Just "quux"
But that produces an error message which is not very understandable for me. What is the right way to do this?
Upvotes: 3
Views: 1068
Reputation: 2472
The problem was actually caused by cabal hell and cleaning up ~/.ghc
directory was necessary to make it work.
Upvotes: -1
Reputation: 10228
Try this on for size:
{-# LANGUAGE TemplateHaskell #-}
module Main where
import qualified Data.Map.Strict as Map
import Control.Lens
data MyLabel =
MyLabel { _label :: String } deriving (Show, Eq, Ord)
data MyMap =
MyMap { _vals :: Map.Map String MyLabel } deriving (Show, Eq, Ord)
makeLenses ''MyLabel
makeLenses ''MyMap
sample :: MyMap
sample =
MyMap (Map.fromList [("foo", MyLabel "bar")])
main :: IO ()
main =
print (sample & (vals . at "foo" . _Just . label .~ "quux"))
Remember that, when setting, you're trying to build a function of type MyMap -> MyMap
. The way you do that is by chaining a bunch of optics together (vals . at "foo" . _Just . label
) and then choosing a setter operation (.~
). You can't mix and match a getter operation like ^.
with a setter operation like .~
! So every setter more or less looks like this:
foo' = (optic1 . optic2 . optic3 . optic4) .~ value $ foo
-- _________this has type Foo -> Foo___________
And to improve readability we use &
, the flipped version of $
:
foo' = foo & (optic1 . optic2 . optic3 . optic4) .~ value
Upvotes: 9