1

我想更好地理解以下代码

的实例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

但特别是,看起来他们正在使用诸如Uint8etc. 之类的某些类型,我不确定这些是在哪里定义的,或者为什么Word8不使用 eg 来代替。另外,不确定如何%s使用。#我在hsc2hs 文档中看到很多参考资料,但到目前为止还没有关于%.

4

1 回答 1

3

关键是链接文档中的粗体句子:

#let ⟨name⟩ ⟨parameters⟩ = "⟨definition⟩&quot;

定义要应用于 Haskell 源的宏。参数名称以逗号分隔,不在括号内。此类宏作为其他#-constructs 调用,以#name 开头。该定义将作为 printf 的参数放在括号内的 C 程序中。要引用参数,请关闭引号,输入参数名称并再次打开引号,以连接 C 字符串文字。或者使用 printf 的格式指令。参数的值必须作为字符串给出,除非宏使用 C 预处理器的 #parameter 语法将它们本身字符串化。

%s在中指定一个字符串参数(您可以在此处printf查看更完整的说明)。

所以不Uint8涉及类型;它只是一个字符串,当您将其替换为numarray您得到

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

这种类型记录在这里

type MUint8 = Word8
于 2020-05-27T19:29:46.493 回答