美文网首页
Haskell中Storable的使用

Haskell中Storable的使用

作者: DarkBubble | 来源:发表于2018-06-18 12:46 被阅读12次

Haskell支持指针和堆内存的分配和使用,主要使用Foreign模块里面的功能。要使用Haskell的指针类型(主要是Ptr a)需要满足(Storable a)。在GHCI中查看class Storable接口的定义:

Prelude> import Foreign
Prelude Foreign> :i Storable 
class Storable a where
  sizeOf :: a -> Int
  alignment :: a -> Int
  peekElemOff :: Ptr a -> Int -> IO a
  pokeElemOff :: Ptr a -> Int -> a -> IO ()
  peekByteOff :: Ptr b -> Int -> IO a
  pokeByteOff :: Ptr b -> Int -> a -> IO ()
  peek :: Ptr a -> IO a
  poke :: Ptr a -> a -> IO ()
  {-# MINIMAL sizeOf,
              alignment,
              (peek | peekElemOff | peekByteOff),
              (poke | pokeElemOff | pokeByteOff) #-}
    -- Defined in ‘Foreign.Storable’

我们假设要实现一个代数数据类型的Storable Instance,参考下面的例子:

  1 import Foreign
  2 
  3 data MyData = MyData Int Double deriving(Eq, Show, Read)
  4 
  5 instance Storable MyData where
  6     sizeOf _ = 16
  7     alignment _ = 8
  8     peek ptr = let ptr_x = castPtr ptr :: Ptr Int
  9                    ptr_y = castPtr (ptr_x `advancePtr` 1) :: Ptr Double
 10                in  do x <- peek ptr_x
 11                       y <- peek ptr_y
 12                       return $ MyData x y
 13     poke ptr d = let ptr_x = castPtr ptr :: Ptr Int
 14                      ptr_y = castPtr (ptr_x `advancePtr` 1) :: Ptr Double
 15                      MyData x y = d
 16                  in  do poke ptr_x x
 17                         poke ptr_y y

对于一个带参类型,实现Storable Instance还需要注意下面的问题:

  1. 自定义ADT中,要求所有被存储在堆内存的成员数据类型也是Storable Instance
  2. 自定义ADT中,sizeOfalignment两个接口尽量使用_来作为输入参数,而不要对ADT数据进行任意部分的求值,否则可能引起malloc接口的错误,因为malloc接口会使用undefined作为构造ADT的参数,一旦求值即会报错
  3. 要实现上述要求必须开启ScopedTypeVariable语法扩展,即作用域类型变量,也就是作为参数类型a可以用于undefined :: a
    例如:
{-# LANGUAGE ScopedTypeVariable #-}

data Vector a = Vector a a a deriving(Eq, Show, Read)

instance Storable a => Storable (Vector a) where
    sizeOf _ = sizeOf (undefined :: a) * 3 -- Scoped type variable 'a'
    alignment _ = sizeOf (undefined :: a) -- Scoped type variable 'a'
    {- ... -}

相关文章

  • Haskell中Storable的使用

    Haskell支持指针和堆内存的分配和使用,主要使用Foreign模块里面的功能。要使用Haskell的指针类型(...

  • 01 数据类型

    swift中结构体在haskell中的描述 枚举类型在haskell中的描述 枚举携带类型在haskell中描述 ...

  • python中的函数式编程函数compose

    python中的函数式编程函数compose 我不认为自己是函数式编程方面的专家,但是大量使用Haskell,Li...

  • 05 递归

    Haskell 中没有 for 和 while 循环,而使用递归解决循环问题。 所谓递归,就是将一个大问题分解为两...

  • 函数式的宗教-00: 认识lisp(clojure)与haske

    总体大纲: lisp与haskell简单介绍 lisp与haskell应用领域 lisp与haskell技术分析 ...

  • 写了个筛法,clojure版和haskell版

    从自然数中筛选出素数 haskell只用了一行 觉得同为函数式编程语言的clojure不会输给haskell,于是...

  • monad以及monad的四条定理

    haskell的范畴是hask范畴(haskell的所有类型隶属于hask范畴),所以haskell的所有函子都是...

  • 使用Haskell读写文件

    1. 直接读写文本文件 Haskell的Prelude库提供了两个函数用来直接读写文本文件,分别是readFile...

  • 实现一个简单的 Timer

    使用 haskell 重新写 Periodic task system 时,我找不到一个合适的 timer 于是...

  • python实现快速排序

    受Haskell的快排启发 尝试了用python实现: 使用python实现更容易理解了(:зゝ∠)

网友评论

      本文标题:Haskell中Storable的使用

      本文链接:https://www.haomeiwen.com/subject/qfwieftx.html