Operations for sequentially ordered types.
spago install enums
Module documentation is published on Pursuit.
Operations for sequentially ordered types
License: BSD 3-Clause "New" or "Revised" License
Operations for sequentially ordered types.
spago install enums
Module documentation is published on Pursuit.
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
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
.
Yes, Int
violates a lot of typeclass laws... But the BoundedEnum
instance having a cardinality of -1 seems particularly egregious. It certainly trapped me. Is this instance worth keeping despite that?
Once purescript/purescript#3058 is merged, perhaps BoundedEnum
could get a new param, with its cardinality defined at type level, with a fundep from the type to the cardinality.
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?
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
Thoughts on adding this?
upFromIncluding :: ∀ a u. Enum a => Unfoldable u => a -> NonEmpty u a
upFromIncluding x = NonEmpty x $ upFrom x
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
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
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?
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?
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
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 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
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.