Giter VIP home page Giter VIP logo

fastsum's People

Contributors

joshvera avatar michaelxavier avatar patrickt avatar proofofkeags avatar robrix 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fastsum's Issues

Problem with Apply instance

The following code demonstrates the problem:

works :: (Apply Eq1 r, Eq v) => Sum r v -> Sum r v -> Bool
works x y = x == y

-- Could not deduce (Apply Eq1 (Const () : r))
fails :: (Apply Eq1 r, Eq v) => Sum r v -> Sum r v -> Bool
fails x y = weaken @_ @_ @(Const ()) x == weaken y

Of course, if I try to provide the missing instance it complains about overlap. So how do I convince it that if Apply Eq1 r, then clearly Apply Eq1 (Const () : r), since there is both Eq1 for Const and Eq for ()?

Some lensy bits for your review

I've found these useful as a UI for fastsum in my lens-oriented code:

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}

module Journal.SumLens where

import Control.Lens
import Data.Constraint
import Data.Sum

projected :: e :< r => Prism' (Sum r v) (e v)
projected = prism' inject project

projectedC :: forall r v e. Const e :< r => Prism' (Sum r v) e
projectedC = prism' (inject . Const) (fmap getConst . project)

weakened :: Prism' (Sum (e ': r) v) (Sum r v)
weakened = prism' weaken $ \s -> case decompose s of
  Left es -> Just es
  Right _ -> Nothing

_shead :: Prism' (Sum (e ': r) v) (e v)
_shead = projected

_stail :: Prism' (Sum (e ': r) v) (Sum r v)
_stail = weakened

underneath :: e :< r => Prism' (Sum (s ': r) v) (e v)
underneath = weakened . projected

underneathC :: Const e :< r => Prism' (Sum (s ': r) v) e
underneathC = weakened . projectedC

decomposed :: Iso' (Sum (e ': r) v) (Either (Sum r v) (e v))
decomposed = iso decompose (either weaken inject)

-- | @applied@ is the optic version of apply, to make it easy to compose
--   applications with other optics:
--   @@
--   s ^. applied @Printable printItem
--     === apply @Printable printItem s
--   @@
applied ::
  forall c r v a.
  Apply c r =>
  (forall f. c f => f v -> a) ->
  Fold (Sum r v) a
applied k f s = s <$ f (apply @c k s)

-- | @HasTraversal'@ serves the same role as Apply, but for traversals across
--   sums that support a given optic. For example, and with direct analogy to
--   'Apply':
--   @@
--   class HasLot f where
--     _Lot :: Traversal' (f v) Lot
--
--   instance HasTraversal' HasLot fs => HasLot (Sum fs) where
--     _Lot = traversing @HasLot _Lot
--   @@
class HasTraversal' (c :: (* -> *) -> Constraint) (fs :: [* -> *]) where
  traversing :: (forall g. c g => Traversal' (g a) b) -> Traversal' (Sum fs a) b

instance c t => HasTraversal' c '[t] where
  traversing k f s = fmap inject (k f (decomposeLast s))

instance
  {-# OVERLAPPING #-}
  (HasTraversal' c (u ': r), c t) =>
  HasTraversal' c (t ': u ': r)
  where
  traversing k f s = case decompose s of
    Right e -> inject <$> k f e
    Left es -> weaken <$> traversing @c k f es

Build fails with ghc-8.6.4 internal error

When trying to build the package with cabal, I encounter the following error:

Resolving dependencies...
Configuring fastsum-0.1.1.0...
Preprocessing library for fastsum-0.1.1.0..
Building library for fastsum-0.1.1.0..
[1 of 2] Compiling Data.Sum.Templates ( src/Data/Sum/Templates.hs, dist/build/Data/Sum/Templates.o )
[2 of 2] Compiling Data.Sum         ( src/Data/Sum.hs, dist/build/Data/Sum.o )
ghc: internal error: Unable to commit 1048576 bytes of memory
    (GHC version 8.6.4 for x86_64_unknown_linux)
    Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug
Failed to install fastsum-0.1.1.0
cabal: Error: some packages failed to install:
fastsum-0.1.1.0-GQUPDK7HNQ3BzBCRuqjYJ7 failed during the building phase. The
exception was:
ExitFailure (-6)

I'm using:

cabal-install version 2.4.1.0
compiled using version 2.4.1.0 of the Cabal library

This seems to be a memory problem and I observe the 4GB of the memory on the VM are consumed by the ghc process before the failure.

Any help solving this issue would be great.

Is :> too rigid?

I'm trying to figure out how to get the following to work:

stronger :: f :< r => Sum r v -> a
stronger = undefined

weaker :: f :< r => Sum (e ': r) v -> a
weaker = stronger

I would think that f :> r entails the constraint f :> any ': r, but this does not seem to be the case. Intuitively I would see the entailment as just a Succ on the former witness. Instead, the error I get is:

• Could not deduce (KnownNat (ElemIndex f0 (e : r)))
    arising from a use of ‘stronger’
  from the context: f :< r
    bound by the type signature for:
               weaker :: forall (f :: * -> *) (r :: [* -> *]) (e :: * -> *) v.
                         (f :< r) =>
                         Sum (e : r) v -> f v
    at /Users/johnw/src/trade-journal/src/Journal/SumLens.hs:74:1-41
  The type variable ‘f0’ is ambiguous
  Relevant bindings include
    weaker :: Sum (e : r) v -> f v
      (bound at /Users/johnw/src/trade-journal/src/Journal/SumLens.hs:75:1)

Requiring Show1 for Show, Eq1 for Eq, etc., is inconvenient

Once upon a time, fastsum had separate Apply and Apply1 typeclasses s.t. we could use Apply for Show and Apply1 for Functor. We eventually got rid of the former because compile times were already far too high, and instead used Show1 to provide our Show instance.

However, while it’s easy to derive Show instances, Show1 is not derivable, so you have to do a bunch of extra work just to show your Sums.

Populate as the inverse of Apply

The following typeclass makes it possible to "populate" a sum by attempting a series of operations in MonadPlus, for example parsers:

class Producible m f where
  produce :: m (f v)

class Populate m (fs :: [* -> *]) where
  populate :: m (Sum fs b)

instance (Producible m t, MonadPlus m) => Populate m '[t] where
  populate = fmap inject (produce @m @t)

instance
  {-# OVERLAPPING #-}
  (Populate m (u ': r), Producible m t, MonadPlus m) =>
  Populate m (t ': u ': r)
  where
  populate =
    fmap inject (produce @m @t)
      <|> fmap weaken (populate @m @(u ': r))

This could be implemented for a Megaparsec type as follows:

instance Producible Parser (Const Entry) where
  produce = fmap Const parseEntry

Now you can populate a Sum '[Const a, Const b, Const c] v as long as there are parsers that can produce values of type a, b and c.

DecomposeSum

Greetings!

We had talked about a combinator to decompose a sum which could be used in pattern matching. It would remove the head of the type list and return either the matched value or a sum with that type removed. Here's what I've got:

-- | Try to extract the first type from the sum. On failure, return a
-- sum that eliminates that as a possibility. This would probably have
-- to be exported by the library so we don't have to export the Sum
-- constructor.
decomposeSum :: Sum (e ': es) b -> Either (Sum es b) (e b)
decomposeSum sum@(Sum n v) = maybe (Left (Sum (n - 1) v)) Right (projectSum sum)


-- | For a sum with precisely one type in the type list, we can safely
-- project that value.
decomposeLast :: Sum '[e] b -> e b
decomposeLast = either (error "impossible") id . decomposeSum

Would you accept a PR with these combinators? Also, are there any other tasks I could help with to get this package ready for a hackage release?

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.