How to compare lenses in Haskell

114 Views Asked by At

I am curious about Eq instance for lenses. Lenses are functions. It is hard to compare arbitrary functions, but lenses are special class of functions.

I am thinking about using QuickCheck Arbitrary instances for s type:

lensesAreEqual :: 
  (Arbitrary a, Eq a) => 
  Lens' s a -> 
  Lens' s a -> 
  Gen Bool
lensesAreEqual l1 l2 = 
  and <$> forM [0..100] $ \_ -> do
    s <- arbitrary
    pure $ s ^. l1 == s ^.l2

I can hind lensesAreEqual monad behind unsafePerformIO for a neat Eq instance.

Does anybody know better solution?

1

There are 1 best solutions below

0
Daniel Wagner On

Don't do this. Instead, define a real data type with the usual Equality, together with an interpretation function:

data ItemType = Weapons | Armor | Potions deriving (Eq, Ord, Read, Show)

data AppState a = AppState
    { _weapons :: [a]
    , _armor :: [a]
    , _potions :: [a]
    , _activeType :: ItemType
    } deriving (Eq, Ord, Read, Show)

toLens :: ItemType -> Lens (AppState a) (AppState b) [a] [b]
toLens Weapons = weapons
toLens Armor = armor
toLens Potions = potions

(This is what was meant in the comments about "defunctionalization".)