Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 安全转换为Word8_Haskell - Fatal编程技术网

Haskell 安全转换为Word8

Haskell 安全转换为Word8,haskell,Haskell,请看以下代码段: 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 我有点惊讶于444被隐式转换为188,就像在不安全的C中一样。在我看来,它非常容易出错。在Haskell中,安全处理此类转换的惯用方法是什么 更新 这似乎只是文字的多态行为

请看以下代码段:

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
我有点惊讶于444被隐式转换为188,就像在不安全的C中一样。在我看来,它非常容易出错。在Haskell中,安全处理此类转换的惯用方法是什么

更新


这似乎只是文字的多态行为,现代编译器对此提出了警告。最重要的是类型系统不允许这种隐式截断
Foo(444::Int)
生成类型不匹配,因此如果值仅在运行时已知,则这是完全安全的。

我不知道惯用语,但您遇到的问题基本上是,文本在超出范围时被截断。由于文本在
Num
上是多态的,而且
Integral
s也需要
Num
,因此您有相应的函数

fromInteger :: Num a => Integer -> a
toInteger :: Integral a => a -> Integer
因此,在转换之前,您始终可以将它们作为
整数进行比较:

-- 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
然后您可以使用
foo
作为智能构造函数:

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

GHC最近增加了一条警告,以提醒此类案例。对于GHC 7.8.3,我看到:

Prelude Data.Word> Foo 444

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

因此惯用的解决方案是使用最流行的编译器的最新版本。

为什么会不安全?@Arnon更新了这个问题。我认为它不仅适用于文本,而且适用于任意值(例如从stdin读取)。谢谢。我担心类型系统允许隐式截断C中的整数(Int到Word8)。这似乎只是文字的多态行为,并且
Foo(444::Int)
生成类型不匹配。所以,这实际上是相当安全的。
$ 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