How can I present data with additional fields at the level level?

I am working on data for a control flow that has a value (polymorphic, it can be anything), and it can also have a validator function that checks if this value is all, and can have a function that "updates" the value "(returns new data with a new value).

In vanilla Haskell, this might look like this:

data MyData a = MyData
  {value :: a
  ,validator :: Maybe (a -> Bool)
  ,refresher :: Maybe (MyData a -> MyData a)}

I really want these types:

data Refreshable = Refreshable | NotRefreshable
data Validatable = Validatable | NotValidatable
MyData (r :: Refreshable) (v :: Validatable)

I did just that, but only with Refreshable. I want to do this with help Validatable, but I have a problem with the constructors. Just for RefreshableI need to have two constructors: one for updated data and the other for non-reactive data. With validatable I will need to have 4 constructors! (for refreshable and validatable, for not refreshable and validatable, for validatable and non-refreshable, and for non-refreshable and non-validatable). And imagine if I need another optional field later. Even worse: almost all fields are the same, except for those that change, so there is a lot of duplication.


/ .
, MyData 'Refreshable 'NotValidatable Refreshable data => data, MyData , .

, ; ( ).


, , XY; , , , Refreshable a Validatable a, MyData, , . , .

? 4- ? , , ? ( : P).

+4
2

- ?

import Control.Applicative (Const)
import Data.Functor.Identity

data MyData kv kr a = MyData
  {value :: a
  ,validator :: kv (a -> Bool)
  ,refresher :: kr (MyData a -> MyData a)}

-- examples
type FullData a      = Data Identity   Identity   a
type EmptyData a     = Data (Const ()) (Const ()) a
type ValidableData a = Data Identity   (Const ()) a

/ ( Identity).

type Present = Identity type Missing = Const () .


,

data MyData (v :: Opt) (r :: Opt) a = MyData
  {value :: a
  ,validator :: Validator v a
  ,refresher :: Refresher r a}

data Opt = Yes | No

type family Validator (o :: Opt) a where
    Validator Yes = (a -> Bool)
    Validator No  = ()
-- etc.

-- examples
type FullData a      = Data Yes Yes a
type EmptyData a     = Data No  No  a
type ValidableData a = Data Yes No  a
+6

:

data Opt = Yes | No

type family TOpt (o :: Opt) a where
  TOpt Yes a = a
  TOpt No a = ()

- :

data MyData (v :: Opt) a = MyData
  {val :: a
  ,validator :: TOpt v (MyData 'Yes a -> Bool)
  ...
  }
+2

All Articles