Make lenses (TH) with the same field name using makeClassy

This question is about Edward A. Kmett lens package (version 4.13)

I have several different types data, all of which have a field that indicates the maximum number of elements contained (a business rule is subject to a change in runtime, and not to a collection implementation problem). I would like to name this field capacityin all cases, but I quickly ran into namespace conflicts.

In the documentation, lensI see that there is a template makeClassy, but I can not find the documentation for it that I understand. Will this template function allow me to have multiple lenses with the same name?


EDITED : Let me add that I am quite capable of coding the problem. I would like to know if the problem will resolve makeClassy.

+4
source share
3 answers

I found the documentation a bit obscure; had to find out what various things Control.Lens.TH did through experimentation.

What do you want - makeFields:

{-# LANGUAGE FunctionalDependencies
           , MultiParamTypeClasses
           , TemplateHaskell
  #-}

module Foo
where

import Control.Lens

data Foo
  = Foo { fooCapacity :: Int }
  deriving (Eq, Show)
$(makeFields ''Foo)

data Bar
  = Bar { barCapacity :: Double }
  deriving (Eq, Show)
$(makeFields ''Bar)

Then in ghci:

*Foo
λ let f = Foo 3
|     b = Bar 7
| 
b :: Bar
f :: Foo

*Foo
λ fooCapacity f
3
it :: Int

*Foo
λ barCapacity b
7.0
it :: Double

*Foo
λ f ^. capacity
3
it :: Int

*Foo
λ b ^. capacity
7.0
it :: Double

λ :info HasCapacity 
class HasCapacity s a | s -> a where
  capacity :: Lens' s a
    -- Defined at Foo.hs:14:3
instance HasCapacity Foo Int -- Defined at Foo.hs:14:3
instance HasCapacity Bar Double -- Defined at Foo.hs:19:3

, , HasCapacity s a, - s a (a , s ). "capcity", ( ) ; , , , . makeFieldsWith lensRules, .

, ghci -ddump-splices Foo.hs:

[1 of 1] Compiling Foo              ( Foo.hs, interpreted )
Foo.hs:14:3-18: Splicing declarations
    makeFields ''Foo
  ======>
    class HasCapacity s a | s -> a where
      capacity :: Lens' s a
    instance HasCapacity Foo Int where
      {-# INLINE capacity #-}
      capacity = iso (\ (Foo x_a7fG) -> x_a7fG) Foo
Foo.hs:19:3-18: Splicing declarations
    makeFields ''Bar
  ======>
    instance HasCapacity Bar Double where
      {-# INLINE capacity #-}
      capacity = iso (\ (Bar x_a7ne) -> x_a7ne) Bar
Ok, modules loaded: Foo.

, splace HasCapcity Foo; Bar.

, HasCapcity ; makeFields . , , ( ), capacity, .


makeClassy . :

data Foo
  = Foo { _capacity :: Int }
  deriving (Eq, Show)
$(makeClassy ''Foo)

(, makeClassy , )

, -ddump-:

[1 of 1] Compiling Foo              ( Foo.hs, interpreted )
Foo.hs:14:3-18: Splicing declarations
    makeClassy ''Foo
  ======>
    class HasFoo c_a85j where
      foo :: Lens' c_a85j Foo
      capacity :: Lens' c_a85j Int
      {-# INLINE capacity #-}
      capacity = (.) foo capacity
    instance HasFoo Foo where
      {-# INLINE capacity #-}
      foo = id
      capacity = iso (\ (Foo x_a85k) -> x_a85k) Foo
Ok, modules loaded: Foo.

- HasFoo, HasCapacity; , - -, Foo, Foo. , capcity Int, , , makeFields. ( HasFoo Foo, Foo id):

*Foo
λ let f = Foo 3
| 
f :: Foo

*Foo
λ f ^. capacity
3
it :: Int

capcity, .

+5

; .

class Capacitor s where
  capacitance :: Lens' s Int

.


, :

data Luggage a = Luggage { clothes :: a, capacity :: !Int }
+1

, makeFields:

data Structure = Structure { _structureCapacity :: Int }
makeFields ''Structure

data OtherStructure = OtherStructure { _otherStructureCapacity :: String }
makeFields ''Structure
0
source

Source: https://habr.com/ru/post/1622961/


All Articles