3 ms·
> It feels a little redundant to have to manually list out all the elements when the information is known statically, and updating the list will be necessary if
by throwaway183839 12y ago
> It feels a little redundant to have to manually list out all the elements when the information is known statically, and updating the list will be necessary if the Peg type changes. In Racket, writing a macro for this would be trivial, but alas, this is Haskell. Perhaps there is a way, I’m just not aware of it.
A reasonably clean way would be to define
data Color = Red | Green | Blue | Yellow | Orange | Purple
deriving (Enum, Bounded, Show)
and then (e.g. in ghci) you can do
>> [minBound .. maxBound] :: [Color]
[Red,Green,Blue,Yellow,Orange,Purple]
I often define the useful function
enumerate :: (Enum a, Bounded a) => [a]
enumerate = [minBound .. maxBound]
for exactly this purpose.
- lexi-lambda 12y agoYep, I posted this on r/haskell and someone pointed this out, which is cool. The provided type for Peg didn't derive Enum or Bounded, but it's a good trick to know.
- deleted 12y ago[deleted]
- throwaway183839 12y agoI'm kind of surprised that `enumerate` isn't defined in any standard libraries (as far as I know) since I need it pretty often. After a while spent programming in Haskell you would probably develop your own mini-library of functions that make your life easier. Another one I often find useful is (.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d (.:) f g = \x y -> f (g x y) which e.g. allows you to define the absolute distance function dist :: (Num a) => a -> a -> a dist = abs .: (-) A fun challenge is figuring out why the definition of (.:) is equivalent to (.:) = fmap . fmap !
- JadeNB 12y ago> A fun challenge is figuring out why the definition of (.:) is equivalent to > (.:) = fmap . fmap > ! Of course it's not really equivalent, since the most general type of the LHS is as you have said, whereas that of the RHS involves functor constraints; but inlining the definition of `fmap` for arrows gives the amusing definition: (.:) = (.) . (.) I tend to figure this sort of thing out by successive eta conversion: \f g x y -> f (g x y) \f g x y -> (f . g x) y \f g x -> f . g x \f g x -> ((f .) . g) x \f g -> (f .) . g \f g -> ((f .) .) g \f -> ((f .) .) \f -> (.) (f .) \f -> (.) ((.) f) \f -> ((.) . (.)) f (.) . (.) Is there a better way?
- wz1000 12y ago(.:) f g = (f .) . g This can interestingly be generalized(in a way) to get (.::) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> d (.::) f g = ((f .) .) . g and so on. Since fmap = (.), substitution would get your point free form.
- HanyouHottie 12y agoSeems like a better name for it would be (...) :: (c -> d) -> (a -> b -> c) -> a -> b -> d since (...) = (.) . (.) .
- cschneid 12y agoThe downside of using (.:) is that it is used heavily in other libraries (Aeson for instance) in a very different context (field accessors, similar in look to json's `:`).