Вы правы в том, что типы Word8.word
, Word32.word
и Word64.word
имеют только общий тип 'a
, который обычно не может быть преобразован в Word64.word
через параметрический полиморфизм .
Точная функция, которую вы ищете может (и должен ) была:
Word<N>.toLargeWord : word -> LargeWord.word
К сожалению, как вы обнаружили, кажется, чтоLargeWord.word
- это псевдоним Word32
, а не Word64
в SML / NJ.Не похоже, что Basis указывает, что LargeWord.word
должен сделать это, но реальность.В Poly / ML похоже, что LargeWord.wordSize
- 126, а в московском ML нет структуры LargeWord
!Вздох.Но, по крайней мере, в Poly / ML он может содержать Word64.word
.
В свете этого я бы предложил одну из двух вещей:
Вы можете использовать ad-hoc полиморфизм : поскольку все три модуля имеют общую подпись WORD
и эта подпись содержит, среди прочего:
val toLargeInt : word -> LargeInt.int
Так что взлом может бытьпреобразовать в LargeInt.int
и затем в Word64.word
: вы можете построить функтор , который принимает один модуль с подписью 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
, должна была избежатьit.
В качестве альтернативы, если вы предпочитаете избегать использования этого дополнительного функтора и целых чисел произвольной точности в качестве промежуточного представления, поскольку это неэффективно и не нужно, вы можете изменить стандартную библиотеку LargeWord :> WORD
так что предполагается использование Word64
вместо.
Этого можно было бы избежать, если бы стандартная библиотека была написана в стиле функториала с LargeWord
, имеющим / являющимся фиксированным параметром где-то, где вы могли бы переопределить его.Но это также сделало бы стандартную библиотеку более сложной.
Что касается конструкции системы модулей ML, я думаю, что выбор размещения toLargeWord
в сигнатуре WORD
является одним из подходов, который очень удобен, потому что вы нене нужно много экземпляров функторов, но, как вы видели, не очень расширяемых.Вы можете увидеть различные философии, применяемые в библиотеках OCaml Base и Core Джейн Стрит, где в Core у вас есть, например, Char.Map.t
(удобно), а в Base у вас есть Map.M(Char).t
(расширяемый).
IПредполагается, что все ваши слова без знака.