我找不到addWithCarry :: Word8 -> Word8 -> (Word8, Bool)
base
中已经定义的函数。唯一记录为关心携带的功能似乎在GHC.Prim
中addIntC#
,但它似乎从未通过各种抽象层向上推。
显然可以通过测试输出值是否在范围内来推出自己的输出值,这实际上是我目前正在做的事情,但我宁愿重用一个(可能更有效的)已经定义的值。
有这样的事情吗?
如果您查看 Word8 的 Num 实例的源代码,您会发现一切都是通过转换为Word#
未装箱值并对其执行操作来完成的,然后缩小到 8 位值。我怀疑对Word#
值进行比较会更有效,所以我实现了这样的事情。它在lpaste上可用(我发现它比StackOverflow更容易阅读)。
请注意,它包括测试套件和标准基准。在我的系统上,所有各种测试对于盒装版本(user5402 的实现)需要 ~31ns,对于 primops 版本需要 ~24ns。
上面 lpaste 的重要函数是 primops
,即:
primops :: Word8 -> Word8 -> (Word8, Bool)
primops (W8# x#) (W8# y#) =
(W8# (narrow8Word# z#), isTrue# (gtWord# z# 255##))
where
z# = plusWord# x# y#
一种方法是:
addWithCarry :: Word8 -> Word8 -> (Word8, Bool)
addWithCarry x y = (z, carry)
where z = x + y
carry = z < x