ITプロに「本物のプログラマはHaskellを使う」が連載されていますが、今回の記事はは「第58回 Cの配列をHaskellで利用する」です。
丁度配列を使いたいところでした。しかし、Array 型は、参照は O(1) で出来ますが、 更新には O(n) かかります。
そこで、記事を写経しながら、Cの配列を使う練習をしてみました。
- Array.hs
-- $ ghc -Wall carray.h carray.c Array.hs import Foreign.C.Types ( CInt(..) ) import Foreign.Marshal.Array import Foreign.Ptr ( Ptr(..) ) main :: IO () main = do let xs :: [CInt] xs = [0..9] len = length xs ys <- withArray xs $ \carr -> do cUpdateArray carr 0 (fromIntegral 123) cUpdateArray carr 4 (fromIntegral 999) print =<< cGetArrayElem carr 0 -- > 123 print =<< cGetArrayElem carr 1 -- > 1 print =<< cGetArrayElem carr 2 -- > 2 print =<< cGetArrayElem carr 3 -- > 3 print =<< cGetArrayElem carr 4 -- > 999 peekArray len carr print ys -- > [123,1,2,3,999,5,6,7,8,9] foreign import ccall "updateArray" cUpdateArray :: Ptr CInt -> CInt -> CInt -> IO () foreign import ccall "getArrayElem" cGetArrayElem :: Ptr CInt -> CInt -> IO CInt
- carray.h
void updateArray ( int*, int, int ); int getArrayElem ( int *, int);
- carray.c
#include "carray.h" void updateArray ( int *xs, int p, int x) { xs[p] = x;} int getArrayElem ( int *xs, int p) { return xs[p];}
$ ghc carray.h carray.c Array.hs [1 of 1] Compiling Main ( Array.hs, Array.o ) Linking Array.exe ... $ ./Array 123 1 2 3 999 [123,1,2,3,999,5,6,7,8,9]