Что такое% в препроцессоре Haskell и как он соотносится с такими типами, как Uint8 (если вообще)?

Я хотел бы лучше понять следующий код в целом.

Примеры для MDouble включены во фрагмент, чтобы продемонстрировать пример, в котором препроцессор не используется.

#let numarray t = "\
foreign import ccall unsafe mxIs%s :: MXArrayPtr -> IO CBool\n\
instance MXArrayComponent M%s where\n\
  isMXArray a = boolC =.< withMXArray a mxIs%s\n\
  createMXArray s = withNDims s (uncurry $ createNumericArray (mxClassOf (undefined :: M%s)) False) >>= mkMXArray\n\
  \
mxArrayGetOffset = arrayDataGet ;\
mxArraySetOffset = arrayDataSet ;\
mxArrayGetOffsetList = arrayDataGetList ;\
mxArraySetOffsetList = arrayDataSetList\
  \n\
instance MXArrayData MX%s M%s\
", #t, #t, #t, #t, #t, #t
foreign import ccall unsafe mxIsDouble :: MXArrayPtr -> IO CBool
foreign import ccall unsafe mxCreateDoubleScalar :: MXDouble -> IO MXArrayPtr
foreign import ccall unsafe mxGetScalar :: MXArrayPtr -> IO MXDouble
instance MXArrayComponent MDouble where
  isMXArray a = boolC =.< withMXArray a mxIsDouble
  createMXScalar = mxCreateDoubleScalar . hs2mx >=> mkMXArray
  mxScalarGet a = withMXArray a mxGetScalar
  createMXArray s = withNDims s (uncurry $ createNumericArray (mxClassOf (undefined :: Double)) False) >>= mkMXArray
  #arrayDataComponent
instance MXArrayData MXDouble MDouble
#numarray Single
#numarray Int8
#numarray Int16
#numarray Int32
#numarray Int64
#numarray Uint8
#numarray Uint16
#numarray Uint32
#numarray Uint64

Но, в частности, похоже, что они используют такие типы, как Uint8 и т.д., и я не уверен, где они определены или почему, например Word8вместо этого не используется. Кроме того, не уверен, как%sиспользуется. Я вижу много ссылок на#в документации по hsc2hs, но пока ничего о%.

1 ответ

Решение

Ключевые предложения выделены жирным шрифтом в связанных документах:

#let ⟨name⟩ ⟨parameters⟩ = "⟨definition⟩"

Определяет макрос, который будет применяться к исходному тексту Haskell. Имена параметров разделяются запятыми, а не внутри скобок. Такой макрос вызывается, как и другие #-конструкции, начиная с #name. Определение будет помещено в программу C внутри скобок в качестве аргументов printf. Чтобы сослаться на параметр, закройте кавычку, введите имя параметра и снова откройте кавычку, чтобы строковые литералы C могли объединяться. Или используйте директивы формата printf. Значения аргументов должны быть представлены в виде строк, если макрос сам не преобразовывает их в строку с помощью синтаксиса #parameter препроцессора C.

%s указывает строковый параметр в printf(и вы можете увидеть более полное объяснение, например, здесь).

Так что нет Uint8тип задействован; это просто строка, и когда вы подставляете ее вnumarray Вы получаете

foreign import ccall unsafe mxIsUint8 :: MXArrayPtr -> IO CBool
instance MXArrayComponent MUint8 where
  ...

и этот тип задокументирован здесь:

type MUint8 = Word8
Другие вопросы по тегам