我在以下函数中有数字换行问题:
f :: Word8 -> Word8 -> Word8
f a b = (a + b) `mod` 255
Run Code Online (Sandbox Code Playgroud)
想法是将两个数字加在一起,模数255(注意255,而不是模256).
显然,答案f 252 8应该是260 mod 255 = 5,但是上面的函数实际上返回4因为252 + 8包裹到4,因为Word8只能保存最多255的数字.从不应用mod函数.
我试过了:
f :: Word8 -> Word8 -> Word8
f a b = (fromIntegral a + fromIntegral b) `mod` 255
Run Code Online (Sandbox Code Playgroud)
认为它将隐含地施放Integer或Int,但它没有.什么是正确的解决方案,以便f不受包装问题的影响而且效率不高?
既然你要求它返回一个Word8,我们可以推断出mod两个参数都是Word8,因此参数+都是两个Word8,因此fromIntegral实际上推断它们具有类型Word8 -> Word8- 可能不是你想要的!
一个修复是真正转换为Integer(或您喜欢的其他类型)暂时,然后回到Word8:
f a b = fromInteger ((fromIntegral a + fromIntegral b) `mod` 255)
Run Code Online (Sandbox Code Playgroud)
另一种解决方案是手动检查是否发生了溢出.
f a b = (sum + if sum < a then 1 else 0) `mod` 255
where sum = a + b
Run Code Online (Sandbox Code Playgroud)
(这里的最终mod操作确实是必需的,万一sum是255因为没有发生溢出!)