如何使用 setter 与多态类型?
How to use setter with polymorphic type?
在这种情况下如何使用镜头(setter)?
模块 A:
data Xxx a = Xxx {
_xxxAaa :: Int,
_xxxBbb :: a
}
makeFields ''Xxx
模块 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
错误是:
• 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 .........
顺便说一句,这个技巧适用于元组(它们也是多态的),但不适用于这种类型。
makeFields
生成的HasBbb
class不提供变型镜头:
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
将其与 makeLenses
生成的 Xxx
专用镜头进行对比:
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]
在这种情况下如何使用镜头(setter)?
模块 A:
data Xxx a = Xxx {
_xxxAaa :: Int,
_xxxBbb :: a
}
makeFields ''Xxx
模块 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
错误是:
• 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 .........
顺便说一句,这个技巧适用于元组(它们也是多态的),但不适用于这种类型。
makeFields
生成的HasBbb
class不提供变型镜头:
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
将其与 makeLenses
生成的 Xxx
专用镜头进行对比:
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]