如何避免指示性多态性并定义lens的lens
How to avoid impredicative polymorphism and define lens of lens
我正在尝试为具有镜头场的数据类型生成镜头。
data St st l = St {
_st_s :: String,
_st_lens :: Lens' st l
}
st_lens :: forall st l. Lens' (St st l) (Lens' st l)
st_lens = lens _st_lens (\s a -> s { _st_lens = a })
GHC 8.10.7 给我一个错误:
Illegal polymorphic type:
forall (f1 :: * -> *). Functor f1 => (l -> f1 l) -> st -> f1 st
GHC doesn't yet support impredicative polymorphism
• In the expansion of type synonym ‘Lens’
{-# Language ImpredicativeTypes #-}
{-# Language TypeApplications #-}
-- ..
st_lens :: forall st l. Lens' (St st l) (Lens' st l)
st_lens = lens @_ @(Lens' st l) _st_lens \s a -> s { _st_lens = a }
使用 GHC 9.2 或更高版本,您可以打开 ImpredicativeTypes
,如 . If you can't switch GHC versions right now, one pre-9.2 alternative is storing your lens as an ALens
, and then using either cloneLens
or the adapted combinators 所示以使用它:
data St st l = St {
_st_s :: String,
_st_lens :: ALens' st l
}
st_lens :: forall st l. Lens' (St st l) (ALens' st l)
st_lens = lens _st_lens (\s a -> s { _st_lens = a })
ghci> ("foo", 15) ^# (St "bar" _1 ^. st_lens)
"foo"
ghci> ("foo", 15) ^. cloneLens (St "bar" _1 ^. st_lens)
"foo"
我正在尝试为具有镜头场的数据类型生成镜头。
data St st l = St {
_st_s :: String,
_st_lens :: Lens' st l
}
st_lens :: forall st l. Lens' (St st l) (Lens' st l)
st_lens = lens _st_lens (\s a -> s { _st_lens = a })
GHC 8.10.7 给我一个错误:
Illegal polymorphic type:
forall (f1 :: * -> *). Functor f1 => (l -> f1 l) -> st -> f1 st
GHC doesn't yet support impredicative polymorphism
• In the expansion of type synonym ‘Lens’
{-# Language ImpredicativeTypes #-}
{-# Language TypeApplications #-}
-- ..
st_lens :: forall st l. Lens' (St st l) (Lens' st l)
st_lens = lens @_ @(Lens' st l) _st_lens \s a -> s { _st_lens = a }
使用 GHC 9.2 或更高版本,您可以打开 ImpredicativeTypes
,如 ALens
, and then using either cloneLens
or the adapted combinators 所示以使用它:
data St st l = St {
_st_s :: String,
_st_lens :: ALens' st l
}
st_lens :: forall st l. Lens' (St st l) (ALens' st l)
st_lens = lens _st_lens (\s a -> s { _st_lens = a })
ghci> ("foo", 15) ^# (St "bar" _1 ^. st_lens)
"foo"
ghci> ("foo", 15) ^. cloneLens (St "bar" _1 ^. st_lens)
"foo"