Consider the following example
module A where
import Control.Lens
data A = A { _aFoo :: Int, _aBar :: String }
makeFields ''Amodule B where
import Control.Lens
import A
data B
= B1 { _bFoo :: Int, _bBar :: Bool }
| B2 { _bFoo :: Int }
makeFields ''Blens-bug/B.hs:10:1: error:
• Could not deduce (Applicative f) arising from a use of ‘pure’
from the context: Functor f
bound by the type signature for:
bar :: Functor f => (Bool -> f Bool) -> B -> f B
at B.hs:10:1-14
Possible fix:
add (Applicative f) to the context of
the type signature for:
bar :: Functor f => (Bool -> f Bool) -> B -> f B
• In the expression: pure (B2 x1_a6s2)
In an equation for ‘bar’: bar _ (B2 x1_a6s2) = pure (B2 x1_a6s2)
In the instance declaration for ‘HasBar B Bool’
- Swapping
import AinBwithimport BinAmakesbaraTraversaleverywhere, i.e. you can't use it as aLensanymore (noviewwithout aMonoidinstance, ...) - Associated type family don't support polymorphic types (i.e. you can't do
type LensChoice A Int = Lens' A Int), so you have to useReifiedLensetc, which is a headache - Even if they did, you'd run into ambiguous types that require proxies or type application;
view (runLens foo) (A 1 "b")fails to typecheck
Don't use makeFields, it's a red herring.
Alternatively, don't write records with partial accessors, or if you do, don't use
makeFieldson them. This is a small price to pay for the convenience ofmakeFields.(Disclaimer: I really like
makeFields, and also I find it upsetting when people make strong claims like “don't use X” based on just one case where X fails to be useful.)