Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Last active August 22, 2023 21:27
Show Gist options
  • Save CMCDragonkai/652f49f9c9edf2551610 to your computer and use it in GitHub Desktop.
Save CMCDragonkai/652f49f9c9edf2551610 to your computer and use it in GitHub Desktop.
Haskell: List Generators like Python's range!
-- comments will show python's equivalent
-- range(1, 11)
a = [1..10]
-- itertools.count()
b = [1..]
-- range(1, 9, 2)
c = [1, 3..7]
-- range(1, 8, 2)
d = [1, 3..8]
istrue1 = c == d
-- itertools.count(1, 3)
e = [1, 4..]
-- list(itertools.islice(itertools.count(1,3), 10))
f = take 10 [1, 4..]
-- list(range(10,-11,-1))
g = [10, 9..( -10)]
-- range(10)
h = [0..10]
-- np.arange(1, 8, 0.5)
i = [1, 1.5..7]
-- np.arange(1,round(4.5),1)
j = [1, 2..round(4.5)]
-- impossible!
k = [(LT)..(GT)]
-- impossible!
l = [(False)..]
-- impossible!
m = [(GT), (EQ)..]
-- can be done, but it's no way near as expressive
n = ['a'..'z']
-- enumerate([0,1,2,3,4], start=1)
o = enumerate 1 [0,1,2,3,4] where
enumerate start = zip [start..]
{-
What is interesting is that Haskell is far more terse.
It's also somewhat more intuitive with the last number being inclusive.
Furthermore the stepping pattern is automatically derived from the first 2 numbers.
Unlike in Python, where you need to explicitly pass the stepping number yourself.
This makes the code far more declarative.
The support for codata (infinite data) is obviously better in Haskell with its
laziness by default.
Stepping in fractional is actually well supported out of the box in Haskell,
whereas Python requires building a function.
Furthermore the Haskell version may look like syntax, but it's just an infix
function. Any type under the Enum class can be put inside the generator expression.
The `[(False)..]` doesn't actually give an infinite list, since it's enumeration
is bounded.
This could be infinitely applied to any kind of enumerative mathematical object.
Such as a pack of cards, the letters of the alphabet, pokemon... etc.
As `[..]` is just syntax sugar for the enum* functions in the Enum typeclass.
Beware of floating point imprecision! `[0.0, 0.1..1.0]` gets you strange numbers!
Better to use `map (/10) [0..10]`.
As a side note:
Given one calls that the list type is a recursive data type, and others have said
that list data is a corecursive data structure. Does that mean corecursive values
inhabit recursive types? A recursive tree type, can therefore be inhabited by
infinite trees.
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment