标准 ML 中 Word64 的多态转换
Polymorphic coersion to Word64 in Standard ML
我想创建一个多态函数,将 8、16、32 位字转换为 64 位字。我该怎么做?
更新 1
在基础库中,所有的词结构都有函数toLarge
和fromLarge
将to/from转换为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
实际上,我希望能够使用 (<<) 运算符 "promote" 将较小的单词转换为较大的单词,但不知道该怎么做。
更新4
好像Word
和LargeWord
依赖架构,代表一个机器字。因为SML/NJ不支持64位arch,所以字长不同
我的结论是,没有办法以多态方式实现它。相反,必须使用适当的 toLarge/fromLarge
方法,如下所示:
fun toWord64 (w : Word8.word) : Word64.word = Word64.fromLarge (Word8.toLarge w)
我可以直接使用 toLarge
,但我想确保结果值为 Word64
。这将使用 SML/NJ 进行编译,但调用此函数将导致运行时异常。
顺便说一句,我没有找到如何从 32 位字节数组中提取 Word64 的方法SML/NJ。
你说得对,类型 Word8.word
、Word32.word
和 Word64.word
仅共享通用类型 'a
,通常不能转换为 Word64.word
通过 参数多态性 .
您正在寻找的确切功能可能(和应该)是:
Word<N>.toLargeWord : word -> LargeWord.word
不幸的是,正如您所发现的,LargeWord.word
似乎是 Word32
的别名,而不是 SML/NJ 中的 Word64
。看起来不像Basis指定LargeWord.word
必须这样做,而是现实。在 Poly/ML 中 LargeWord.wordSize
似乎是 126 而在 Moscow ML 中没有 LargeWord
结构!叹。但至少在 Poly/ML 它可以包含一个 Word64.word
.
鉴于此,我建议以下两点之一:
您可以使用 ad-hoc 多态性:因为所有三个模块共享签名 WORD
并且此签名持有,除其他外:
val toLargeInt : word -> LargeInt.int
所以一个 hack 可能是转换为 LargeInt.int
,然后向下转换为 Word64.word
:您可以构建一个 functor,它需要一个模块WORD
签名和 return 包含转换为 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
having/being 参数固定在某个地方,您可以覆盖它,这本可以避免。但它也会使标准库更加复杂。
关于 ML 模块系统设计,我认为选择将 toLargeWord
放在 WORD
签名中是一种非常方便的方法,因为您不需要很多仿函数实例,但是,正如您所见,不是很可扩展。您可以看到 Jane Street 的 OCaml 库 Base 和 Core 中应用的不同哲学,在 Core 中您有例如Char.Map.t
(方便),在 Base 中你有 Map.M(Char).t
(可扩展)。
我假设你的话都是无符号的
我想创建一个多态函数,将 8、16、32 位字转换为 64 位字。我该怎么做?
更新 1
在基础库中,所有的词结构都有函数toLarge
和fromLarge
将to/from转换为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
实际上,我希望能够使用 (<<) 运算符 "promote" 将较小的单词转换为较大的单词,但不知道该怎么做。
更新4
好像Word
和LargeWord
依赖架构,代表一个机器字。因为SML/NJ不支持64位arch,所以字长不同
我的结论是,没有办法以多态方式实现它。相反,必须使用适当的 toLarge/fromLarge
方法,如下所示:
fun toWord64 (w : Word8.word) : Word64.word = Word64.fromLarge (Word8.toLarge w)
我可以直接使用 toLarge
,但我想确保结果值为 Word64
。这将使用 SML/NJ 进行编译,但调用此函数将导致运行时异常。
顺便说一句,我没有找到如何从 32 位字节数组中提取 Word64 的方法SML/NJ。
你说得对,类型 Word8.word
、Word32.word
和 Word64.word
仅共享通用类型 'a
,通常不能转换为 Word64.word
通过 参数多态性 .
您正在寻找的确切功能可能(和应该)是:
Word<N>.toLargeWord : word -> LargeWord.word
不幸的是,正如您所发现的,LargeWord.word
似乎是 Word32
的别名,而不是 SML/NJ 中的 Word64
。看起来不像Basis指定LargeWord.word
必须这样做,而是现实。在 Poly/ML 中 LargeWord.wordSize
似乎是 126 而在 Moscow ML 中没有 LargeWord
结构!叹。但至少在 Poly/ML 它可以包含一个 Word64.word
.
鉴于此,我建议以下两点之一:
您可以使用 ad-hoc 多态性:因为所有三个模块共享签名
WORD
并且此签名持有,除其他外:val toLargeInt : word -> LargeInt.int
所以一个 hack 可能是转换为
的结构LargeInt.int
,然后向下转换为Word64.word
:您可以构建一个 functor,它需要一个模块WORD
签名和 return 包含转换为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
having/being 参数固定在某个地方,您可以覆盖它,这本可以避免。但它也会使标准库更加复杂。
关于 ML 模块系统设计,我认为选择将 toLargeWord
放在 WORD
签名中是一种非常方便的方法,因为您不需要很多仿函数实例,但是,正如您所见,不是很可扩展。您可以看到 Jane Street 的 OCaml 库 Base 和 Core 中应用的不同哲学,在 Core 中您有例如Char.Map.t
(方便),在 Base 中你有 Map.M(Char).t
(可扩展)。
我假设你的话都是无符号的