Examiner les dossiers et leurs objectifs suivants:Comment appliquer le même objectif sur deux enregistrements différents? (? Ou, champ d'enregistrement des noms comme valeurs de première classe)
data Bar = Bar {barField1 :: Int, barField2 :: String}
makeLensesWith abbreviatedFields ''Bar
data BarError = BarError {barerrField1 :: [String], barerrField2 :: [String]}
makeLensesWith abbreviatedFields ''BarError
Maintenant, tous les deux ont accès aux lentilles field1
& field2
en vertu de la mise en œuvre du HasField1
et HasField2
classes de type. Cependant, je ne peux pas obtenir le morceau de code suivant pour compiler:
-- Most-general type-signature inferred by the compiler, if I remove the
-- KindSignatures from `record` & `errRecord` below:
--
-- validateLength :: (IsString a) => (Int, Int) -> ALens t t [a] [a] -> t -> t -> t
--
validateLength (mn, mx) l (record :: Bar) (errRecord :: BarErr) =
let len = length (record ^# l)
in if ((len<mn) || (len>mx))
then errRecord & l #%~ (\x -> ("incorrect length"):x)
else errRecord
-- Usage scenario:
--
-- let x = Bar 10 "hello there"
-- xErr = BarError [] []
-- in validateLength (3, 10) field2 x xErr
Message d'erreur:
/Users/saurabhnanda/projects/vl-haskell/src/TryLens.hs:18:20: error:
• Couldn't match type ‘BarError’ with ‘Bar’
Expected type: BarError -> BarError
Actual type: Bar -> BarError
• In the second argument of ‘(&)’, namely
‘l #%~ (\ x -> ("incorrect length") : x)’
In the expression:
errRecord & l #%~ (\ x -> ("incorrect length") : x)
In the expression:
if ((len < mn) || (len > mx)) then
errRecord & l #%~ (\ x -> ("incorrect length") : x)
else
errRecord
Note: Au lieu d'utiliser ^.
et %~
J'utilise ^#
et #%~
parce que Je voudrais
Modifier: Un extrait plus simple pour illustrer le problème est:
-- intended type signature:
-- funkyLensAccess :: l -> r1 -> r2 -> (t1, t2)
--
-- type signature inferred by the compiler
-- funkyLensAccess :: Getting t s t -> s -> s -> (t, t)
--
funkyLensAccess l rec1 rec2 = (rec1 ^. l, rec2 ^. l)
Type sig please ... – leftaroundabout
Je ne suis pas sûr de la bonne signature de type et je laisse le compilateur déduire la signature de type. Je vais mettre la signature de type inférée dans la question, ce qui rendra évident pourquoi ce n'est pas une vérification de type. Dans ce cas, veuillez considérer l'intention de la question - J'essaie de comprendre comment écrire ce morceau de code. –
@leftaroundabout Fait! –