Giter Site home page Giter Site logo

data-fix's Issues

Add Hashable instance

It would be nice to have a hashable instance for Fix. It could be defined with Hashable1. I would PR this if you would take it.

Existentially quantified types for hoistFix

Thank you for the library!

Why existentially quantified types for
hoistFix :: Functor f => (forall a. f a -> g a) -> Fix f -> Fix g
and
hoistFix' :: Functor g => (forall a. f a -> g a) -> Fix f -> Fix g
type annotations. But not simply
hoistFix :: Functor f => (f (Fix g) -> g (Fix g)) -> Fix f -> Fix g
and
hoistFix' :: Functor g => (f (Fix f) -> g (Fix f)) -> Fix f -> Fix g
Probably the original idea behind was to map f -> g to Fix f -> Fix g.
But in fact the proposed method are more general.

Migrate away from Eq1/Ord1/Show1

Continuing on haskell/core-libraries-committee#190 (comment), I propose to migrate from

instance Eq1 f => Eq (Fix f)
instance Ord1 f => Ord (Fix f)
instance Show1 f => Show (Fix f)

to

instance Eq (f (Fix f)) => Eq (Fix f)
instance Ord (f (Fix f)) => Ord (Fix f)
instance Show (f (Fix f)) => Show (Fix f)

or if you fancy QuantifiedContraints

instance (forall a. Eq a => Eq (f a)) => Eq (Fix f)
instance (forall a. Ord a => Ord (f a)) => Ord (Fix f)
instance (forall a. Show a => Show (f a)) => Show (Fix f)

The motivation is that I recently migrated a codebase from a homegrown newtype Fix with instance Ord (f (Fix f)) => Ord (Fix f) to data-fix and hit performance issues. They were a combination of several factors:

  • I used Data.Functor.Classes.Generic to derive Ord1 instance generically. It appeared that from and to survived in Core, despite pretty aggressive optimization options. This is admittedly not a fault of data-fix, but a general issue with usability of Eq1 / Ord1 / Show1. I had to write all instances manually.

  • class Ord1 contains only liftCompare, but no liftLT, liftLE, liftGT, liftGE, so it has no access to <, <=, >=, > of the base functor. This implies that < on Fix f also necessarily goes through compare and takes a performance hit.

  • It does not seem that liftEq / liftCompare can be optimized away unless the base functor f is completely monomorphic and everything is forced to inline. E. g., (==) specialised to Fix (ListF Int) looks reasonable, but (==) for Fix (ListF a) goes through liftEq. The Core for

    instance Eq (f (Fix f)) => Eq (Fix f) where
      (==) = coerce ((==) @(f (Fix f)))

    looks more reasonable to me.


I understand that the proposed change is a breaking one. It is however not very pronounced: in recent base we have class (forall a. Eq f a) => Eq1 f, so the majority of users will not even notice. It's only if you require Eq (Fix f) as a constraint, but use liftEq inside, which will explode, because Eq1 f is no longer guaranteed. I think, however, that GHC would yell if encounters Eq (Fix f) constraint, suggesting to replace it with Eq1 f.

@phadej what do you think?

Use Eq1, Show1, etc. for instances

Since base-4.9, the Data.Functor.Classes module has been available (previously, it was available through the transformers library). It would be nice if the instances for Fix relied on these instead of using FlexibleContexts. I am willing to PR this if you would accept it.

Not an issue - just a question about the haskell type system that came to my mind by looking at data-fix

Please excuse if this is a dumb question 😃

Maybe I just missing some special Haskell syntax - but I don't find a good explanation for:

type MyMaybe :: Type -> Type
type MyMaybe = Maybe

type MyMaybe' :: Type -> Type
type MyMaybe' a = Maybe a

type Works = Fix MyMaybe

-- • The type synonym ‘MyMaybe'’ should have 1 argument, but has been given none
-- • In the type synonym declaration for ‘DoesntWork’
type DoesntWork = Fix MyMaybe'

Here for sure the argument can be avoided - but what if the type is nested - e.g. something like Either (Maybe a ) ()? How to apply Fix in such a case?

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.