Внедрение аппликативных эффектов в поля HKD с Барби или Хигледи - PullRequest
1 голос
/ 28 марта 2020

Я использую barbies-th, чтобы превратить тип записи в тип данных с более высоким родом:

declareBareB [d|
  data Foo = MkFoo
      { field1 :: Int
      , field2 :: Bool
      } |]

Затем я могу написать функцию для pu sh любой аппликативный эффект в отдельные поля:

bdistribute :: (Applicative f) => f (Foo Bare Identity) -> Foo Covered f
bdistribute foo = MkFoo
    { field1 = field1 <$> foo
    , field2 = field2 <$> foo
    }

Но мне кажется, что я должен написать bdistribute раз и навсегда для всех HKD в стиле Barb ie. Другими словами, я ищу двойника Хигглиди construct. У Хиггли есть два метода в классе типов Construct:

construct :: HKD structure f -> f structure
deconstruct :: structure -> HKD structure f

, но я бы хотел

nstruct :: (Applicative f) => f structure -> HKD structure f

Мозговой штурм ниже: одна идея, которую я только что высказал, заключается в том, что эта проблема можно упростить написание следующей функции:

shape :: Foo Covered ((->) (Foo Bare Identity))
shape = MkFoo
    { field1 = field1
    , field2 = field2
    }

с тех пор мы имеем

bdistribute :: (Applicative f) => f (Foo Bare Identity) -> Foo Covered f
bdistribute = bmap (<$> x) shape

В более общем смысле, из shape мы также можем написать

bdistribute :: (Functor f, Applicative g, ApplicativeB b, TraversableB b) => f (b g) -> b (Compose f g)
bdistribute x = bmap (\f -> Compose $ fmap f . bsequence' <$> x) shape
...