GithubHelp home page GithubHelp logo

higgledy's People

Contributors

alexfmpe avatar alexpeits avatar alistairb avatar gilligan avatar jonathanlking avatar kcsongor avatar patrickt avatar philonous avatar ryanglscott avatar timsears avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

higgledy's Issues

Prefer Data.Semigroup.Last

From the base-4.12.0 docs...

This type will be marked deprecated in GHC 8.8, and removed in GHC 8.10. Users are advised to use the variant from Data.Semigroup and wrap it in Maybe.

So for example

>>> import Data.Semigroup (Last (..))
>>> type Partial a = HKD a (Maybe (Last a))

Dank library tho my man.

Consider exporting all the things via Internal module and/or export a bit more

I keep doing strange things. Consider something like this:

data Foo = Foo { int :: Int, bool :: Bool } deriving (Generic, ...)

-- uses Read instances to populate corresponding fields
fromPairs :: [(String, String)] -> HKD Foo Maybe

fromPairs [] == Foo Nothing Nothing
fromPairs [("int", "10")] = Foo (Just 10) Nothing
fromPairs [("bool", "False)] = Foo Nothing (Just False)

Implementation uses label internally and since it requires HKD structure f as input I'm using it as label (mempty :: HKD Foo (Const ())). Now, any attempt to make it for any structure fails since required constraint (Monoid tuple, Generic xs, Tuple f xs tuple) => Monoid (HKD xs f) can't be expressed without Tuple class that's not exported.

Something-something internals something (if they could be exposed).

https://stackoverflow.com/questions/9190638/how-why-and-when-to-use-the-internal-modules-pattern

Think about sum types

I haven't thought about them in the context of higgledy but I want to get the ball rolling. Have you already considered what this would look like?

using HKD from class methods

I'm probably trying to do something that should not be done, but I added recLabels to a class I have:

class (Eq a, IRes a, Generic a, Ord a, Read a, Show a, Typeable a)
  => IsDerivedRec a where
  -- ...
  tableName        :: TableName
  tableName        = type2tblName $ typeRep $ Proxy @a
  recLabels        :: Labels a
  recLabels        = label

Resulting in the error:

   Could not deduce (Data.Generic.HKD.Labels.GLabels
                          (GHC.Generics.Rep a))
        arising from a use of label
      from the context: IsDerivedRec a
        bound by the class declaration for IsDerivedRec
        at src/FDS/Data/IsRecord.hs:36:6-17
     In the expression: label
      In an equation for recLabels’: recLabels = label
   |
46 |   recLabels        = label
   |                      ^^^^^

Just curious if it is possible to make this work, or perhaps why not.

COnfusing Emoji choice

why is there a book in the readme I don't understand why this is the most appropriate emoji thnx

empty constructor with alternative

As documentation explains you can create something out of nothing using mempty, which imposes a Monoid constraint on every field which rules out a whole bunch of useful types.

An alternative would be to impose constraint on functor - Alternative f can provide "something" filled with "nothing"

data Foo = Foo Int deriving Generic

nofoo :: Alternative f => HKD Foo f
nofoo = bmap (const empty) (deconstruct (Foo undefined) :: HKD Foo (Const ()))

nofoo can be for example Foo Nothing or Foo (Left "")

Does not build with generic-lens 2.0.0.0

Fails with:

src/Data/Generic/HKD/Named.hs:31:1: error:
    Could not load module ‘Data.GenericLens.Internal’
    It is a member of the hidden package ‘generic-lens-core-2.0.0.0’.
    Perhaps you need to add ‘generic-lens-core’ to the build-depends in your .cabal file.
    It is a member of the hidden package ‘generic-lens-1.1.0.0’.
    Perhaps you need to add ‘generic-lens’ to the build-depends in your .cabal file.
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
   |
31 | import Data.GenericLens.Internal (GUpcast (..))
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

when including generic-lens-core it fails with:

src/Data/Generic/HKD/Named.hs:31:35: error:
    Module ‘Data.GenericLens.Internal’ does not export ‘GUpcast(..)’
   |
31 | import Data.GenericLens.Internal (GUpcast (..))
   |

It seems GUpcast has moved to https://hackage.haskell.org/package/generic-lens-core-2.0.0.0/docs/Data-Generics-Product-Internal-Subtype.html , however, it is no longer an exported module. When exporting it it builds.

I also had to import HList from Data.Generics.Product.Internal.HList.

I'll put up a PR with these changes, but I guess generic-lens would need to be updated to expose GUpcast again?

Something prevents AllB instances from working

Consider following declarations

-- create a datatype using barbie's "native" methods
data X f = X { getX :: f Int } deriving (Generic)
instance FunctorB X
instance TraversableB X
instance ProductB X
instance ConstraintsB X

idX :: X Identity
idX = X (Identity 10)
-- and derive isomorphic datatype using higglegy
data Y = Y { getY :: Int } deriving (Generic)

idY :: HKD Y Identity
idY = deconstruct @ Identity (Y 10)

In both cases we can work with bmap:

> :t bmap (\_ -> Const ()) idX
bmap (\_ -> Const ()) idX :: X (Const ())
> :t bmap (\_ -> Const ()) idY
bmap (\_ -> Const ()) idY :: HKD Y (Const ())

But only "native" version works with bmapC:

> :t bmapC @ Num (fmap (+1)) idX
bmapC @ Num (fmap (+1)) idX :: X Identity
> :t bmapC @ Num (fmap (+1)) idY
<interactive>:1:1: error:
    • Could not deduce: c0 Int arising from a use of ‘bmapC’
    • In the expression: bmapC @Num (fmap (+ 1)) idY

most recent version of everything, ghc 8.6.5 from stack's lts-13.23

DeriveAnyClass for barbie instances

I tried to drop all the implementations of the barbie classes in favour of the shiny new generic rep, but it didn't work immediately. This issue is here as a reminder that there are at least 50 LoC we could drop if I could fix whatever scary error is emerging when I try.

Consider more efficient representation for HKD

I've watched the higgledy from scratch videos, which were fantastic. The first thing that jumped out at me is that in memory representation of HKD Foo is going to be quite in efficient if one would like to do anything other than immediately convert back to a Foo; lots of pointer chasing to get to each field, and the more fields a structure has the worse this would get. I wondered how difficult having HKD(_) internally produce something similar to SuperRecord's FromNative version of Foo, where accessing each field would become a constant time operation, so performance should ideally approach the hand written HKD version of Foo.

I would personally simplify things a little over what SuperRecord does where it sorts the fields, this seems unnecessary.

I'm mostly opening this issue for discussion of the pros and cons, I'm not tied to the exact choice of library (SuperRecord is the only one I have experience with of the anonymous record libraries, and it has excellent performance).

Deriving `Show`, `Eq` and other instances for newtypes over `HKD a f`.

Hey, Tom! Thanks for the lib, I really like the idea :)

The issue

While trying to write an utility using higgledy and ran into the fact that I can't really derive instances easily for a newtype that wraps an HKD a f. Taking Show as an example:

data Wrapper a = Wrapped a | Unwrapped
  deriving (Generic, Eq, Show)
  
newtype Foo a = Foo (HKD a Wrapper)
  deriving (Generic)
  deriving newtype (Show)

If I try to derive Show for the type Foo like above I get the following error:

• Could not deduce (Data.Generic.HKD.Types.GShow 'True (GHKD_ Wrapper (Rep a)))

Have you come across this limitation before? How have you solved it?

Possible solution for specific instances

The issue for Show seems to be that higgledy doesn't export the Data.Generic.HKD.Types.GShow class so it is not possible to add it to the constraints of a standalone instance declaration like so:

deriving instance
  ( Data.Generic.HKD.Types.GShow 'True (GHKD_ Update (Rep a)),
    Generic a
  ) =>
  Show (Changeset a)

Could GShow be exported? It seems to be standard practice (see GFromJSON for example).

Ideal solution

However, the above is just a band-aid, since other instances cannot be derived either.

I wonder if there is a generalized way to do newtype deriving for instances such as Show, Eq, Semigroup and Monoid?

Haddock for Construct should probably mention Applicative

The haddock for Construct is:

class Construct (f :: Type -> Type) (structure :: Type) where
  construct :: HKD structure f -> f structure
  deconstruct :: structure -> HKD structure f

and

(Functor f, Generic structure, GConstruct f (Rep structure)) => Construct f structureSource

this is pretty amazing and sounds like you can deconstruct for any f --- though it seems like it such a thing would require pure. Indeed the implementation has an Applicative f constraint, but this wigged me out for a few minutes!

Consider exposing even more things

In https://github.com/lunaris/generic-validated/blob/master/src/Validated/Codes.hs#L35 I end up needing the ProductBC and GAllB classes/constraint families. I may be doing it wrong, but I think if one wants to write any polymorphic function that uses some of the barbies stuff these are necessary. Not sure if they are clean enough to export, or perhaps some class synonym like class (ProductBC ..., GAllB ...) => BarbieHKD ... would be the right call? Alternatively if there's another way of doing this then let me know.

Natural transformation on HKD types

The Barbies documentation mentions a way to change the "outfits" of a barbie using bmap:

bmap (either (const Nothing) Just) (p :: Person (Either e))

If I try to write a function that uses bmap on an HKD type to achieve a similar effect, I get the following error:

data Wrapper a = Wrapped a | Unwrapped deriving (Generic)

f :: HKD a Wrapper -> HKD a Maybe
f x = bmap g x
  where
    g :: Wrapper a -> Maybe a
    g (Wrapped a) = Just a
    g Unwrapped = Nothing

Error:

• Could not deduce (Data.Generic.HKD.Types.GFunctorB (Rep a)) arising from a use of ‘bmap’

The higgledy documentation mentions:

By combining this with some of the Barbies interface (the entirety of which is available to any HKD-wrapped type) [..]

I assumed using bmap would then just work. Am I doing something wrong? Is it possible to write such a transformation using higgledy?

Allow 'build' with named fields

Currently build is not great to use – you can mix up the field order:

>>> :{
test :: _
test = build @User
:}
...
...  Found type wildcard _
...     standing for f [Char] -> f Int -> f Bool -> HKD User f
...

(Here you can't, but if there were two Ints, you could.)

I propose adding a version that uses the named library:

test
    :: "name"      :! f [Char]
    -> "age"       :! f Int
    -> "likesDogs" :! f Bool
    -> HKD User f
test = buildNamed @User

Then the function can be called like this:

test (#name ...) (#age ...) (#likesDogs ...)

Or in this style, which allows supplying the arguments in any order:

test
    ! #likesDogs ...
    ! #name ...
    ! #age ...

Pretty printing lacks any brackets

There should be brackets inserted around each field when it is printed using Show.

*Main Data.Functor.Identity> deconstruct @Identity (User "abc" 5)
User Identity "abc" Identity 5

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.