Git Product home page Git Product logo

purescript-enums's Introduction

purescript-enums

Latest release Build status Pursuit

Operations for sequentially ordered types.

Installation

spago install enums

Documentation

Module documentation is published on Pursuit.

purescript-enums's People

Contributors

garyb avatar hdgarrood avatar jacereda avatar jbrownson avatar jdegoes avatar jordanmartinez avatar kl0tl avatar liamgoodacre avatar milesfrain avatar nightra avatar paf31 avatar paluh avatar safareli avatar sharkdp avatar tfausak avatar thomashoneyman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

purescript-enums's Issues

Overlapping instances found

Is the problem just this, or are my dependencies messed up?

Compiling Data.Enum
Error found:
Error in module Data.Enum:
Error in value declaration enumChar:
Error at /home/ruben/code/holger/hermit/bower_components/purescript-enums/src/Data/Enum.purs line 113, column 1 - line 121, column 1:
Overlapping instances found for Prelude.Bounded Prim.Char:
Data.Char.boundedChar
Prelude.boundedChar

BoundedOrd

I think it make sense to have BoundedOrd <= Enum?
Currently we have Bounded <= Enum, and if you want to compare you have to use fromEnum.

UnboundedEnum

The current Enum laws don't hold for BoundedEnum.

Shouldn't we have something like class Enum a <= UnboundedEnum a and move there the current Enum laws?

BoundedEnum would then be extended with

forall a > bottom, a < top: pred a < succ a
forall a > bottom, a < top: succ a > pred a
forall a > bottom: pred >=> succ >=> pred = pred
forall a < top: succ >=> pred >=> succ = succ

I don't know who could potentially want to implement UnboundedEnum though, maybe some bigint package? Would it be useful at all?

Inconsistent behavior of enumFromTo for bounded enums

With the canonical Enum instance for the following data type

data T = A | B | C | D

I get:

> enumFromTo A A :: Array T
[A]
> enumFromTo A B :: Array T
[A,B]
> enumFromTo A C :: Array T
[A,B,C]
> enumFromTo A D :: Array T
[A,B,C]

The last one returns a wrong result with the current implementation for enumFromTo because the unfoldr-function calls succ D, which short-circuits in the Maybe monad and breaks the unfoldr 'loop'.

Note: this only fails for bounded Enums

Define BoundedEnum-like class using type-level Ints

With type-level ints, we can actually specify what the bounds are for a given type. For example...

class (Bounded a, Enum a) <= BoundedEnumTL min step max a where
  toEnumTL :: Proxy Int -> a

This would enable one to use toEnum without incurring the Maybe wrapper.

instance BoundedEnumTL 0 1 23 Hour where
  toEnumTL p = Hour $ reflectType p

-- cardinality could likely be calculated
cardinalityTL :: BoundedEnumTL min step max => ... => Proxy Int

toEnumTL (Proxy :: Proxy 4) == Hour 4
toEnumTL (Proxy :: Proxy 26) -- compiler error

See also purescript/purescript-datetime#96

Consider a SmallBounded type

As an alternative to #35 that is a bit easier to deal with but slightly less safe (though unless you are doing some crazy stuff, should be fine most of the time), I would like to ask if we could do the following, and thus resurrect e.g. boundedEnumMaybe:

-- | A lawful class to denote Cardinality a << Cardinality Int
class Bounded a <= SmallBounded a

instance boundedEnumMaybe :: (SmallBounded a, BoundedEnum a)
  => BoundedEnum (MaybeWrapped a) where
    cardinality = Cardinality $ unwrap (cardinality :: Cardinality a) + 1
    toEnum 0 = wrap  Nothing
    toEnum n = wrap $ Just <$> toEnum (n - 1)
    fromEnum Nothing = 0
    fromEnum (Just e) = fromEnum e + 1

Why isn't BoundedEnum constraint used in defaultSucc and defaultPred?

current implementation for defaultSucc and defaultPred is taking toEnum and fromEnum as arguments:

defaultSucc :: forall a. (Int -> Maybe a) -> (a -> Int) -> a -> Maybe a
defaultSucc toEnum' fromEnum' a = toEnum' (fromEnum' a + 1)

defaultPred :: forall a. (Int -> Maybe a) -> (a -> Int) -> a -> Maybe a
defaultPred toEnum' fromEnum' a = toEnum' (fromEnum' a - 1)

When it could also be implemented like this:

defaultSucc ::  a. BoundedEnum a => a -> Maybe a
defaultSucc = toEnum <<< (_ + 1) <<< fromEnum

defaultPred ::  a. BoundedEnum a => a -> Maybe a
defaultPred = toEnum <<< (_ - 1) <<< fromEnum

so why is it like that?

No separation between Enumerable and FinitelyEnumerable

In Haskell's Data.Enumerable there's a distinction between Enumerable and FinitelyEnumerable. This allows for example to have an Enumerable instance for (FinitelyEnumerable a) => List a which is something I'd be interested in at the moment.

It would be possible to do this w/o breaking anything if instead of adding FinitelyEnumerable and changing Enumerable we added the opposite, not sure what it would be called, but maybe NonfinitelyEnumerable or something.

Would you be open to a pull request?

`toEnum` modulo `Cardinality a`

Given a BoundedEnum a, it would be nice to have a function

toEnumModulo :: Int -> a

which would reduce the input modulo Cardinality a and then retrieve the element in the enum, being safe that it will remain in the defined buondary

Incorrect assumptions from BoundedEnum laws.

These instances / functions all require that fromEnum bottom == 0 to work properly, although there is no law to enforce this:

  • BoundedEnum (Maybe a)
  • BoundedEnum (Either a b)
  • BoundedEnum (Tuple a b)
  • defaultToEnum
  • defaultFromEnum
  • toEnumWithDefaults

Two ways to fix this:

  • Add fromEnum bottom == 0 law, this is commonly true, but e. g. not in purescript-dom

  • Rework these instances / functions to work in these edges cases, adding / substracting fromEnum bottom in fromEnum / toEnum respectively.

Unfortunately these are IMO breaking changes.

Why succ returns Maybe?

Why can't I create Enum with succ:: a -> a? For example, it can describe cycled boolean enum, where succ True returns False and succ succ True returns True.

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.