我无法将号码添加到Char
;以下内容将无法编译'a' + 1
。但是,['a'..'z']
成功创建一个字符串,其中每个字符值都会递增。有没有一个特殊的函数可以增加Char
?
我知道我能做到chr (ord c + 1)
.
如何['a'..'z']
或底层enumFromTo
函数增加结果中的字符String
?
是的,有一个特殊的功能可以添加到Char
,来自同一个Enum
类那个enumFromTo
来自,命名为succ
。请注意,它是部分的:succ maxBound
未定义,因此在应用之前请注意检查字符的值succ
. succ
确实是一样的\c -> chr (ord c + 1)
,您可以通过以下方式验证universe
包裹:
> let avoidMaxBound f x = if x == maxBound then Nothing else Just (f x)
> avoidMaxBound succ == avoidMaxBound (\c -> chr (ord c + 1))
True
事实上实施succ in GHC http://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.Enum.html#Enum与您建议的功能非常接近:
instance Enum Char where
succ (C# c#)
| isTrue# (ord# c# /=# 0x10FFFF#) = C# (chr# (ord# c# +# 1#))
| otherwise = error ("Prelude.Enum.Char.succ: bad argument")
然而,succ
不用于执行enumFromTo
in GHC:
instance Enum Char where
{-# INLINE enumFromTo #-}
enumFromTo (C# x) (C# y) = eftChar (ord# x) (ord# y)
{-# RULES
"eftChar" [~1] forall x y. eftChar x y = build (\c n -> eftCharFB c n x y)
#-}
-- 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 c n 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 x y | isTrue# (x ># y ) = []
| otherwise = C# (chr# x) : eftChar (x +# 1#) y
如果你能看清主要出于效率原因而存在的肮脏之处,你就会发现eftChar
本质上是使用succ
,但是它的内联版本而不是实际调用succ
(在这里,为了避免装箱和重新装箱Char
被操纵)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)