Reputation: 3737
How to use lens (setter) in this case?
Module A:
data Xxx a = Xxx {
_xxxAaa :: Int,
_xxxBbb :: a
}
makeFields ''Xxx
Module B:
t :: IO Bool
t = do
let n = "aaa" :: String
let xs = [Xxx 0 0, Xxx 1 1] :: [Xxx Int]
ys = [set bbb n $ x | x <- xs]
pure False
Error is:
• Couldn't match type ‘Int’ with ‘[Char]’
arising from a functional dependency between:
constraint ‘HasBbb (Xxx Int) String’ arising from a use of ‘bbb’
instance ‘HasBbb (Xxx a) a’
at .........
Btw, this trick works with tuples (they are polymorphic too), but not with such type.
Upvotes: 3
Views: 114
Reputation: 34378
The HasBbb
class generated by makeFields
does not offer a type changing lens:
ghci> :i HasBbb
class HasBbb s a | s -> a where
bbb :: Lens' s a
{-# MINIMAL bbb #-}
-- Defined at A.hs:14:1
instance HasBbb (Xxx a) a -- Defined at A.hs:14:1
Contrast it with the Xxx
-specific lens generated by makeLenses
:
data Xxx a = Xxx {
_xxxAaa :: Int,
_xxxBbb :: a
}
makeFields ''Xxx
makeLenses ''Xxx
ghci> :i xxxBbb
xxxBbb :: Lens (Xxx a1) (Xxx a2) a1 a2 -- Defined at A.hs:15:1
ghci> :t set xxxBbb "aaa" (Xxx 0 0)
set xxxBbb "aaa" (Xxx 0 0) :: Xxx [Char]
Upvotes: 4