How does enumFromTo work?

I cannot add a number to Char ; below will not compile 'a' + 1 . Nevertheless, ['a'..'z'] successfully creates a line in which each of the characters is incremented. Is there a special function that can increase a Char ?

I know I can do chr (ord c + 1) .

How does the function ['a'..'z'] or the base enumFromTo increment the characters in the resulting String ?

+7
haskell typeclass
source share
1 answer

Yes, there is a special function that can add to Char from the same Enum class from which enumFromTo is named succ . Remember that it is partial: succ maxBound is undefined, so take care of the meaning of the character before applying succ . succ really matches \c -> chr (ord c + 1) , as you can check with the universe package:

 > let avoidMaxBound fx = if x == maxBound then Nothing else Just (fx) > avoidMaxBound succ == avoidMaxBound (\c -> chr (ord c + 1)) True 

In fact, the succ implementation in GHC is pretty close to the function you suggested:

 instance Enum Char where succ (C# c#) | isTrue# (ord# c# /=# 0x10FFFF#) = C# (chr# (ord# c# +# 1#)) | otherwise = error ("Prelude.Enum.Char.succ: bad argument") 

However, succ not used in the enumFromTo implementation in the GHC:

 instance Enum Char where {-# INLINE enumFromTo #-} enumFromTo (C# x) (C# y) = eftChar (ord# x) (ord# y) {-# RULES "eftChar" [~1] forall x y. eftChar xy = build (\cn -> eftCharFB cnxy) #-} -- We can do better than for Ints because we don't -- have hassles about arithmetic overflow at maxBound {-# INLINE [0] eftCharFB #-} eftCharFB :: (Char -> a -> a) -> a -> Int# -> Int# -> a eftCharFB cn x0 y = go x0 where go x | isTrue# (x ># y) = n | otherwise = C# (chr# x) `c` go (x +# 1#) {-# NOINLINE [1] eftChar #-} eftChar :: Int# -> Int# -> String eftChar xy | isTrue# (x ># y ) = [] | otherwise = C# (chr# x) : eftChar (x +# 1#) y 

If you can squint due to muck, which exists primarily for efficiency reasons, you can see that eftChar essentially uses succ , and the built-in version, rather than the actual call to succ (here, to avoid boxing and re-boxing when manipulating Char ) .

+5
source share

All Articles