GithubHelp home page GithubHelp logo

Comments (9)

fumieval avatar fumieval commented on May 16, 2024 1

FYI barbies-th provides an equivalent AccessorsB class: https://hackage.haskell.org/package/barbies-th-0.1.9/docs/Barbies-TH.html#t:AccessorsB

It would be great to have this in barbies so that barbies-th focus on the Template Haskell part

from barbies.

jcpetruzza avatar jcpetruzza commented on May 16, 2024

I considered something like lenses in the past (maybe for any functor, not just Identity?) but I'm not sure I see usages that are not covered well by generic-lens already. Do you have scenarios where you'd like to operate on all lenses at once?

For btraverse1, would one need a new class? E.g., can't one derive it from btraverse and an auxiliary newtype wrapper that pretends an Apply is actually an Applicative, or something like that?

from barbies.

masaeedu avatar masaeedu commented on May 16, 2024

For btraverse1, would one need a new class? E.g., can't one derive it from btraverse and an auxiliary newtype wrapper that pretends an Apply is actually an Applicative, or something like that?

@jcpetruzza That makes sense at a high level, but I haven't been able to make it work. I think the relevant newtype is MaybeApply f a = Either (f a) a (where Apply f => Applicative (MaybeApply f)). But in order to convert a traversal over MaybeApply f into a traversal over f itself, you end up needing an operation Apply f => Either (f (b g)) (b g) -> f (b g), and I'm honestly not sure how to supply that in general for a "TraversableB HKD with at least one position".

You can instead make it work with something like this as the primitive operation:

bhead :: b f -> Some b

or even:

brefute :: b VoidF -> Void

But this is a bit more mysterious for an implementor.

from barbies.

jcpetruzza avatar jcpetruzza commented on May 16, 2024

I think I wasn't really very clear, sorry! What I meant is that since "Apply is Applicative without pure", and btraverse requires an Applicative but doesn't use pure, we can use a newtype wrapper to pretend an Apply is an Applicative whose pure will never be called. Something like this:

newtype CantUsePure f a = CantUsePure (f a)
  deriving newtype Functor

instance Apply f => Applicative (CantUsePure f) where
  pure = error "Can't use pure!"
  CantUsePure f <*> CantUsePure x = CantUsePure (f <.> x)

btraverse1
  :: (TraversableB b, Apply e)
  => (forall a . f a -> e (g a))
  -> b f
  -> e (b g)
btraverse1 h
  = coerce . btraverse (CantUsePure . h)

Of course, one shouldn't export CantUsePure.

I think I rather not introduce a dependency just for this type of functions; and one could put them in a separate package, anyway

from barbies.

masaeedu avatar masaeedu commented on May 16, 2024

@jcpetruzza The main issue as I understand it is that the quality of "not using pure" isn't attached to f, but to b. In a context where you're abstract in b, and want to demand that b has at least one "position" where f occurs, there doesn't seem to be any safe way to get around requiring a subclass of TraversableB (although the best way to encode its operations is debatable).

Of course we can just use the error technique to bypass the type system and pretend that any TraversableB is Traversable1B, and then blow up at runtime if we've made a mistake. This doesn't seem ideal though, and I'd rather not lie to the consumer of my API in this way.

from barbies.

jcpetruzza avatar jcpetruzza commented on May 16, 2024

You are correct, if you have something that is an Apply and not an Applicative, this method would work as a backdoor only if you control the instances on which you use it. I thought it would always work with the generic instances we provide, but this is not true, since it will currently blow on types that have values not under f.

I still think that there is no difference between TraversableB and Traversable1B, in that, afaics, both have exactly the same instances. If Apply were a super-class of Applicative, we'd just require Apply for the type of the effect instead (the generic instances would just be a bit more complex to write, I think)

from barbies.

jcpetruzza avatar jcpetruzza commented on May 16, 2024

On further thought, Traversable1B has fewer instances than TraversableB, I think. One can't get an instance for:

data Unit (f :: k -> Type) = Unit

or, more in general, for any type with constructors where f does not occur.

from barbies.

masaeedu avatar masaeedu commented on May 16, 2024

@jcpetruzza Yes, exactly. This is why you would want Traversable1B to be a subclass of TraversableB.

If Apply were a super-class of Applicative, we'd just require Apply for the type of the effect instead (the generic instances would just be a bit more complex to write, I think)

Things are a bit confusing here because the relationship between Traversable/Traversable1B and Applicative/Apply is contravariant, so the variance is flipped around. Traversable is a superclass of Traversable1 as a consequence of Applicative being a subclass of Apply.

from barbies.

masaeedu avatar masaeedu commented on May 16, 2024

@fumieval FWIW i've revised my position on the "bag of lenses" class. I now believe that what we want is the class of HKDs that are products. A naive encoding of this is pretty straightforward:

type HKD k = (k -> Type) -> Type

type HList :: [k] -> HKD k
data HList xs f
  where
  HNil :: HList '[] f
  HCons :: f x -> HList xs f -> HList (x ': xs) f

type ProductB :: HKD k -> Constraint
class ProductB (b :: HKD k)
  where
  type Components b :: [k]
  to :: b f -> HList (Components b) f
  from :: HList (Components b) f

-- Laws:
-- to . from = id
-- from . to = id

I believe this would subsume ConstraintsB, and would also supply the bag of lenses we're looking for in certain circumstances. Additionally, it provides a good basis for discussing the duality of products and coproducts and their interactions.

from barbies.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.