gpt4 book ai didi

haskell - enumFromTo 如何工作?

转载 作者:行者123 更新时间:2023-12-02 06:28:57 24 4
gpt4 key购买 nike

我无法向 Char 添加数字;以下代码将无法编译 'a' + 1。但是,['a'..'z'] 成功创建了一个字符串,其中每个字符值都递增。是否有一个可以增加 Char 的特殊函数?

我知道我可以执行chr (ord c + 1)

['a'..'z'] 或底层 enumFromTo 函数如何递增生成的 String 中的字符?

最佳答案

是的,有一个特殊的函数可以添加到 Char,它来自 enumFromTo 所在的同一个 Enum 类,名为 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

事实上implementation of succ in GHC与您建议的功能非常接近:

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

但是,GHC 中 enumFromTo 的实现中并未使用 succ:

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 进行装箱和重新装箱)。

关于haskell - enumFromTo 如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31754011/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com