标准ML中Word64的多态共转换



我想创建一个多态函数,将8,16,32位字转换为64位字。我该怎么做?

更新1

在基本库中,所有的单词结构都有函数toLargefromLarge来转换为LargeWord,据我所知,这只是Word32的同义词。

更新2

根据规范,单词大小必须是2的幂,但在SML/NJ中,我有

Standard ML of New Jersey v110.84 [built: Mon Dec 03 10:23:14 2018]
- Word.wordSize;
val it = 31 : int
- Word32.wordSize;
val it = 32 : int
- Word.toLarge;
val it = fn : word -> Word32.word
> LargeWord.wordSize;
val it = 32 : int

在PolyML 中

Poly/ML 5.7.1 Release
> Word.wordSize;
val it = 63: int
> Word64.wordSize;
val it = 64: int
> Word.toLarge;
val it = fn: word -> ?.word
> LargeWord.wordSize;
val it = 64: int

怎么了?为什么Word.wordSize不是二次幂?为什么Word表示在这些SML实现中有所不同?

更新3

事实上,我希望能够使用(<<(运算符将较小的单词"提升"为较大的单词,但我不知道如何做到这一点

更新4

似乎WordLargeWord依赖于体系结构并表示一个机器字。因为SML/NJ不支持64位arch,所以它有不同的字大小。

您是对的,类型Word8.wordWord32.wordWord64.word只共享公共类型'a,而CCD_11通常不能通过参数多态性转换为Word64.word

您正在寻找的可能(而应该(的确切函数是:

Word<N>.toLargeWord : word -> LargeWord.word

不幸的是,正如您所发现的,在SML/NJ中,LargeWord.word似乎是Word32的别名,而不是Word64。看起来Basis并没有指定LargeWord.word必须这样做,而是现实。在Poly/ML中,似乎LargeWord.wordSize是126,而在Moscow ML中没有LargeWord结构!叹气但至少在Poly/ML中,它可以包含CCD_ 19。

鉴于此,我建议两件事之一:

  1. 您可以使用ad-hoc多态性:由于所有三个模块共享签名WORD,并且该签名保持不变,除其他外:

    val toLargeInt : word -> LargeInt.int
    

    因此,破解方法可能是转换为LargeInt.int,然后再转换为CCD22:您可以构建一个函子,它接受一个具有WORD签名的模块,并返回一个包含到Word64的转换的结构。

    functor ToWord64 (WordN : WORD) = struct
    fun toWord64 (n : WordN.word) : Word64.word =
    Word64.fromLargeInt (WordN.toLargeInt n)
    end
    

    然后,您可以为每种情况实例化这个函子:

    structure Word8ToWord64 = ToWord64(Word8)
    val myWord64 = Word8ToWord64.toWord64 myWord8
    

    这有点混乱,包括LargeWord在内的现有模块的层次结构旨在避免这种情况

  2. 或者,如果您希望避免将这个额外的函子和任意精度整数作为中间表示,因为这既低效又不必要,那么您可以更改标准库的LargeWord :> WORD,使其假定使用Word64

如果标准库是以函数样式编写的,并且LargeWord在某个可以覆盖它的地方固定了一个参数,那么这是可以避免的。但这也会使标准库更加复杂。

关于ML模块系统设计,我认为选择将toLargeWord放在WORD签名中是一种非常方便的方法,因为你不需要很多函子实例,但正如你所看到的,它的可扩展性不是很强。您可以在Jane Street的OCaml库Base和Core中看到应用的不同哲学,其中在Core中有例如Char.Map.t(方便(,在Base中有Map.M(Char).t(可扩展(。

我认为你的话都是无符号的

我得出结论,没有办法以多态的方式实现这一点。相反,必须使用适当的toLarge/fromLarge方法,如以下所示:

fun toWord64 (w : Word8.word) : Word64.word = Word64.fromLarge (Word8.toLarge w)

我可以直接使用toLarge,但我想确保得到的值是Word64。这将使用SML/NJ进行编译,但此函数的调用将导致运行时异常。

顺便说一句,我没有找到如何在32位SML/NJ中从字节数组中提取Word64的方法。

最新更新