4

我有一个 type 的元素Data.Vector.Unboxed.Vector Word32。我想将其转换为本机 JS TypedArrayUint32Array特别是 )。我知道toJsArrayand toJsValListOf,但是这两个函数都处理列表,而不是向量,并且效率低下。如何将未装箱的Vector直接转换为 JS TypedArray

4

1 回答 1

1

我能够解决这个问题,直到编组到一个Int32Array而不是一个Uint32Array;可能实际上已经了解 GHCJS 超过一个小时的人将能够对此进行扩展,以便您获得您的Uint32Array(或者您可以制作一个GHCJS.Buffer支持getUint32Array操作的破解版本)。

这个想法是获取表示的ByteArray基础Vector,然后slice只保留相关部分:

import Data.Vector.Unboxed as V
import Data.Word

import qualified Data.Vector.Unboxed.Base as B
import qualified Data.Vector.Primitive as P
import GHCJS.Types
import qualified GHCJS.Buffer as Buffer
import JavaScript.TypedArray (Int32Array)

-- TODO: generalize this to all types that support unboxed vectors...
toI32Array :: Vector Word32 -> Int32Array
toI32Array (B.V_Word32 (P.Vector offset len bs)) =
    js_slice offset (offset + len) $ Buffer.getInt32Array (Buffer.fromByteArray bs)


foreign import javascript unsafe "$3.slice($1, $2)" js_slice :: Int -> Int -> Int32Array -> Int32Array
-- should be
-- foreign import javascript unsafe "$3.slice($1, $2)" js_slice :: Int -> Int -> SomeTypedArray a m -> SomeTypedArray a m
-- but alas, JavaScript.TypedArray.Internal.Type is a hidden module

这是一些使用它的示例代码:

v :: Vector Word32
v = V.fromList [1, 2, 3]

foreign import javascript unsafe "console.debug($1);" js_debug :: JSVal -> IO ()

main = do
    let v' = toI32Array v
    js_debug $ jsval v'

如果您在浏览器中查看控制台,您可以检查jsval v'确实有 type Int32Array

于 2015-12-23T12:16:42.190 回答