Safe conversion to Word8

Take a look at the following snippet:

Prelude> import Data.Word
Prelude> data Foo = Foo Word8 deriving Show
Prelude> Foo 4
Foo 4
Prelude> Foo 44
Foo 44
Prelude> Foo 444
Foo 188

      

I'm a little surprised that 444 is implicitly converted to 188, as in unsafe C. It looks pretty error prone. What's the idiomatic way to safely deal with such conversions in Haskell?

UPDATE

This seems to be just polymorphic behavior of literals and the modern compiler warns about this. Most importantly, the type system does not allow for such implicit truncation. Foo (444 :: Int)

generates type mismatch, so it is completely safe if the value is known only at runtime.

+3


source to share


2 answers


A warning was recently added to the GHC to cause such cases. With GHC 7.8.3 I see:

Prelude Data.Word> Foo 444

<interactive>:7:5: Warning:
    Literal 444 is out of the Word8 range 0..255
Foo 188
Prelude Data.Word> 

      

And when compiling:



$ ghc so.hs
[1 of 1] Compiling Main             ( so.hs, so.o )

so.hs:5:19: Warning: Literal 444 is out of the Word8 range 0..255

      

So the idiomatic solution is to use the latest version of the most popular compiler.

+6


source


I don't know about the idioms, but the problem you are experiencing is basically that the literal gets truncated when it goes out of bounds. Since literals are polymorphic in Num

, and Integral

require Num

, you have functions

fromInteger :: Num a => Integer -> a
toInteger :: Integral a => a -> Integer

      

Therefore, you can always compare them as Integer

before conversion:



-- Don't export the constructor
data Foo = Foo Word8 deriving (Eq, Show)

foo :: Integral a => a -> Maybe Foo
foo x = if xI > mBW8I then Nothing else Just (Foo $ fromInteger xI)
    where
        xI = toInteger x
        mBW8 :: Word8
        mBW8 = maxBound
        mbW8I = toInteger mBW8

      

Then you can use foo

as a smart constructor:

> foo 4
Just (Foo 4)
> foo 44
Just (Foo 44)
> foo 444
Nothing

      

+2


source







All Articles