Ceci est une version d'un code sur lequel j'ai travaillé, avec les détails supprimés. J'espère que c'est clair ce que j'essaie de faire, mais sinon je peux clarifier. Je suis tout à fait nouveau à l'utilisation des lentilles, et les types compliqués impliqués souvent les faire paraître plus de problèmes que ce qu'ils valent.En boucle sur les lentilles, et en utilisant chacune avec vue et ensemble
-- some data type
type AType = ...
data Thing = Th { _v, _w, _x :: AType, _otherStuff :: ... }
makeLenses ''Thing
-- some operation that can be performed on corresponding x or w or v values in two Things.
f :: AType -> AType -> AType
f = ...
-- apply f to the corresponding v, and w, and x values in a and b; then store each result in the respective field of a, leaving other fields untouched.
transform :: Thing -> Thing -> Thing
transform a b =
let transformVorWorX :: Lens' Thing AType -> AType
transformVorWorX lens =
let vwx = view lens a
vwx' = view lens b
in f vwx vwx'
in foldl (\a' lens -> set lens (transformVorWorX lens) a') a [v,w,x]
Quand je compile, GHC recrache
Could not deduce (f ~ Identity)
from the context (Functor f)
bound by a type expected by the context:
Functor f => (AType -> f AType) -> Thing -> f Thing
at ...
‘f’ is a rigid type variable bound by
a type expected by the context:
Functor f => (AType -> f AType) -> Thing -> f Thing
at ...
Expected type: (AType -> f AType) -> Thing -> f Thing
Actual type: ASetter Thing Thing AType AType
In the first argument of ‘transformVorWorX’, namely ‘lens’
In the second argument of ‘set’, namely ‘(transformVorWorX lens)’
Pourquoi pas ce travail de code? Je ai trouvé que le remplacement lens
avec cloneLens lens
permet de compiler, mais je ne sais pas pourquoi, et cela se sent très laid - y at-il une façon plus élégante de faire ce que je veux, c'est peut-être plus général?
Un grand merci