我为下面的数据类型写了一个可存储的矢量实例(原始问题在这里):
data Atoms = I GHC.Int.Int32 | S GHC.Int.Int16
Run Code Online (Sandbox Code Playgroud)
用于为可存储矢量定义这些实例的代码如下.虽然我使用下面的代码获得了非常好的性能,但我对通用建议非常感兴趣,以提高该可存储实例的性能.通用建议,我的意思是:
如果有任何已知的好的库源代码做类似的事情(即,为union/recursive数据类型定义可存储的实例),我将非常感兴趣检查它们.
import Data.Vector.Storable
import qualified Data.Vector.Storable as V
import Foreign
import Foreign.C.Types
import GHC.Int
data Atoms = I GHC.Int.Int32 | S GHC.Int.Int16
deriving (Show)
instance Storable Atoms where
sizeOf _ = 1 + sizeOf (undefined :: Int32)
alignment _ = 1 + alignment (undefined :: Int32)
{-# INLINE peek #-}
peek p = do
let p1 = (castPtr p::Ptr Word8) `plusPtr` …Run Code Online (Sandbox Code Playgroud) 我试图调试性能问题作为更复杂的代码的一部分.似乎append我用来创建动态的,可增长的向量的(Int,Int,Int,Int)函数导致Int元组中的一个在被写入向量之前被装箱和取消装箱.我写了一个更简单的代码来重现这个问题 - 它似乎只有在我在append函数中添加向量增长功能时才会发生- 下面的示例代码(除了重现问题之外它没有做太多有用的工作),其后的片段core显示了值被装箱和取消装箱:
{-# LANGUAGE BangPatterns #-}
module Test
where
import Data.Vector.Unboxed.Mutable as MU
import Data.Vector.Unboxed as U hiding (mapM_)
import Control.Monad.ST as ST
import Control.Monad.Primitive (PrimState)
import Control.Monad (when)
import GHC.Float.RealFracMethods (int2Float)
import Data.STRef (newSTRef, writeSTRef, readSTRef)
import Data.Word
type MVI1 s = MVector (PrimState (ST s)) Int
type MVI4 s = MVector (PrimState (ST s)) (Int,Int,Int,Int)
data Snakev s = S {-# UNPACK #-}!Int
!(MVI4 s)
newVI1 …Run Code Online (Sandbox Code Playgroud) 当处理vectorif unsafeUpdate_函数用于更新某些元素时,是否可以保持流融合vector?答案在我做的测试中似乎没有.对于下面的代码,临时向量在upd函数中生成,如核心中所确认:
module Main where
import Data.Vector.Unboxed as U
upd :: Vector Int -> Vector Int
upd v = U.unsafeUpdate_ v (U.fromList [0]) (U.fromList [2])
sum :: Vector Int -> Int
sum = U.sum . upd
main = print $ Main.sum $ U.fromList [1..3]
Run Code Online (Sandbox Code Playgroud)
在核心中,$wupd函数被用于sum- 如下所示,它生成新的bytearray:
$wupd :: Vector Int -> Vector Int
$wupd =
\ (w :: Vector Int) ->
case w `cast` ... of _ …Run Code Online (Sandbox Code Playgroud) 我有一个像下面的测试函数,用于runST内部变异状态.我go在其中定义了另一个函数,它返回Int包含在ST结果中(只是玩一些ST概念).问题是我的函数类型签名似乎是错误的.如果我注释掉函数类型签名,代码运行正常.使用注释代码中的类型签名,它不会编译,因为编译器将go函数的状态解释为与封闭范围中的状态不同.我将理解如何定义函数类型签名以将外部函数传递ST s给go函数的指针.
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Data.Word(Word32)
import Data.Vector.Unboxed as U hiding (mapM_,create)
import Control.Monad.ST as ST
import Control.Monad.Primitive (PrimState)
import System.Random.MWC
test :: Word32 -> Int
test x = runST $ do
gen <- initialize (U.singleton $ fromIntegral x :: U.Vector Word32) :: (forall s. ST s (Gen (PrimState (ST s))))
let --go :: Int -> ST s Int …Run Code Online (Sandbox Code Playgroud) 假设我有一个简单的类AClass,其公共成员f1可以被覆盖.有什么方法可以定义AClass与另一个成员的新实例,f2而AClass不是复制源代码?玩具代码如下:
class AClass a where
f1 :: a -> Int
data Val = I Int
instance AClass Val where
f1 x = 0
-- the method below can't be added as it is not public member of AClass
-- f2:: a -> Float
-- f2 x = 0.0
Run Code Online (Sandbox Code Playgroud)
我环顾四周,但没有找到任何关于如何做到这一点的明确例子(即我能理解的例子 - 清晰度是相对的).有什么可能的方法?关闭,新类型声明或其他什么?用上面的玩具代码演示技术会很有帮助 - 你可以改变data声明等(例如,用一个newtype包装器替换它Int),但上面代码中唯一不可变的是类声明AClass.这是因为假设该类已经由库编写者编写,因此,我无法触及它.最终结果应该是另一个继承了好东西的玩具代码AClass,并添加了f2成员.
当然,在这样的重写课程中会有一些警告.但是,它有助于了解什么是可能的,以及如何.
- 更新 -
下面的工作代码 …
你是如何构建IOVector的MVector?IOVector记录为:
type IOVector = MVector RealWorld
Run Code Online (Sandbox Code Playgroud)
我有一个像下面这样的 MVector,并且想要构建 IOVector(用于输入到 MSV.unsafeWith 函数 - MSV 是 Data.Vector.Storable.Mutable 库的简写):
v <- MSV.replicate 5 0 :: (IO (MVector (PrimState IO) CShort))
Run Code Online (Sandbox Code Playgroud) 我收到下面的代码错误 - 我怀疑它与dispatch函数的类型签名有关,它返回一个Vector类型Storable a.有什么简单的方法来更新dispatch功能类型签名只做Int32并CChar在签名类型:
{-# LANGUAGE BangPatterns #-}
import Data.Vector.Storable as SV
import Foreign.C.Types (CChar)
import GHC.Int (Int32)
data AList = I {-# UNPACK #-} !(SV.Vector Int32)
| S {-# UNPACK #-} !(SV.Vector CChar)
dispatch :: (Storable a) => AList -> SV.Vector a
dispatch (I x) = x
dispatch (S x) = x
Run Code Online (Sandbox Code Playgroud)
ghci 7.4.1中的错误:
test.hs:11:18:
Couldn't match type `CChar' with `Int32'
Expected type: Vector a
Actual type: …Run Code Online (Sandbox Code Playgroud) 鉴于下面的代码(来自Yoneda Lemma解释):
{-# LANGUAGE RankNTypes #-}
check1 :: a -> (forall b . (a -> b) -> b)
check1 a f = f a
uncheck1 :: (forall b . (a -> b) -> b) -> a
uncheck1 t = t id
Run Code Online (Sandbox Code Playgroud)
forall量化check1似乎在以下rank-1方面得到证实ghci:
$ :t check1
check1 :: a -> (a -> b) -> b
$ :t uncheck1
uncheck1 :: (forall b. (a -> b) -> b) -> a
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚为什么check1有 …
在Sum of Products方法中,如何检索记录功能?下面带有record datatype(ghc 7.10.3)的示例代码:
{-# LANGUAGE DeriveGeneric #-}
import qualified GHC.Generics as GHC
import Generics.SOP
data Rec = Rec { frec :: Int, srec :: Maybe String}
deriving (Show, GHC.Generic)
instance Generic Rec -- empty
instance HasDatatypeInfo Rec
Run Code Online (Sandbox Code Playgroud)
让我们看看DataTypeInfo ghci提示:
*Main> datatypeInfo (Proxy :: Proxy Rec)
ADT "Main" "Rec" (Record "Rec" (FieldInfo "frec" :* (FieldInfo "srec" :* Nil)) :* Nil)
Run Code Online (Sandbox Code Playgroud)
我们看到frec并且srec都是FieldInfo具有FieldInfo带fieldName字符串的构造函数的类型.所以,我没有看到任何方法来获得实际的功能frec :: Rec …
我无法弄清楚while我在下面写的玩具循环中的错误是什么.它适用于一个输入,但挂起其他输入.这是代码 - while循环采用向量,向量上的谓词和向量上的变换函数,并返回另一个向量:
import Data.Vector.Unboxed as U
while :: Vector Int -> (Vector Int -> Bool) -> (Vector Int -> Vector Int) -> Vector Int
while v p f = go 0 v
where go n x = if (p x) then go (n+1) (f x)
else x
test :: Vector Int -> Vector Int
test a = while a (\x -> (x!0) < 2) (\x -> U.map (+1) a)
main = print $ test (U.fromList [0])
Run Code Online (Sandbox Code Playgroud)
这依赖于执行 …
haskell ×10
vector ×4
fusion ×1
ghc ×1
ghc-generics ×1
loops ×1
optimization ×1
performance ×1
st ×1
storable ×1
stream ×1
typeclass ×1
unboxing ×1