Что такое% в препроцессоре Haskell и как он соотносится с такими типами, как Uint8 (если вообще)? - PullRequest
1 голос
/ 27 мая 2020

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

Экземпляры для 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 et c., И я не уверен, где они определены, или почему, например, Word8 вместо этого не используется. Кроме того, не знаю, как используется %s. Я вижу много ссылок на # в hsc2hs docs , но пока ничего о %.

1 Ответ

3 голосов
/ 27 мая 2020

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

#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
...