我想创建一个多态函数,将8,16,32位字转换为64位字。我该怎么做?
更新1
在基本库中,所有的单词结构都有函数toLarge
和fromLarge
来转换为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
似乎Word
和LargeWord
依赖于体系结构并表示一个机器字。因为SML/NJ不支持64位arch,所以它有不同的字大小。
您是对的,类型Word8.word
、Word32.word
和Word64.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。
鉴于此,我建议两件事之一:
您可以使用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
在内的现有模块的层次结构旨在避免这种情况或者,如果您希望避免将这个额外的函子和任意精度整数作为中间表示,因为这既低效又不必要,那么您可以更改标准库的
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的方法。