gpt4 book ai didi

haskell - 在可变函数中获取不可变向量的类型

转载 作者:行者123 更新时间:2023-12-02 03:34:17 25 4
gpt4 key购买 nike

我有一个简单的就地函数,我正在使用可变向量来实现它。但是,此函数需要一个向量,使用不可变向量最容易构造该向量。下面是一些演示基本结构的玩具代码(但可能无法编译):

import Data.Vector.Generic as V
import Data.Vector.Unboxed as U

myvec :: (Vector v r) => Int -> v r
myvec i = V.generate i id

f :: (MVector v r, PrimMonad m) => v (PrimState m) r -> m ()
f y = let v = myvec 10 -- what should the type of `v` be?
--the following doesn't work since the Mutable type family is not injective:
_ = return v `asTypeOf` unsafeFreeze y
in do ....


main = do
-- at the top level, I know the input can be unboxed
let v = U.generate 10 (+(1::Int))
v' <- thaw v
f v'
y <- freeze v'
print y

我看不到 f 有任何方法可以为 v 确定(有效的)不可变向量类型。我只是让 myvec 生成一个多态的 mutable 向量类型,但即使对于上面的简单函数,myvec 的代码也更加丑陋。

我正在寻找一个解决方案,让我可以

  1. 轻松定义 myvec(如上定义)(我看不出有任何方法可以用可变向量干净利落地做到这一点)
  2. 尽可能使用最具体的向量类型:例如,一种解决方案是让 myvec 返回一个盒装向量,它可以容纳任何 r 类型。但是,我们关心速度,因此如果 f 的输入是可变的未装箱向量,myvec 应该是可变的未装箱向量或不可变的未装箱向量。
  3. 我还试图避免从main(其中不可变类型已知)传入myvec:我们有足够的信息来生成 在本地 f 中,因此不需要从 main 传递矢量(除了可能的类型信息)。

最佳答案

经过一番挖掘,我想出了如何编写一个可变的 generate 函数:

import Data.Vector.Generic.Mutable as M
import Data.Vector.Fusion.Stream as S
import Control.Monad.Primitive

mutableGenerate :: (MVector v r, PrimMonad m) => Int -> (Int -> r) -> m (v (PrimState m) r)
mutableGenerate i f = M.unstream $ S.generate i f

这允许我生成一个多态可变向量,但带有不可变向量的简洁符号。在我看来,这像是一个有用的函数,应该包含在 Data.Vector.Generic.Mutable 中。

关于haskell - 在可变函数中获取不可变向量的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24702588/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com