Haskell からは C の関数が呼べます。
{-# OPTIONS -fglasgow-exts #-} import Foreign import Foreign.C.String import Foreign.C.Types import System.IO.Unsafe (unsafePerformIO) foreign import ccall "math.h sin" c_sin :: Double -> Double foreign import ccall "string.h strlen" c_strlen :: CString -> CUInt -- 同じ printf をHaskellでは2種類定義してみました。 foreign import ccall "stdio.h printf" c_printf :: CString -> IO () foreign import ccall "stdio.h printf" c_print2 :: CString -> Double -> IO () main = do -- 参考:ホワット・ア・ワンダフル・ワールド :: FFI とか Eval とか -- http://alohakun.blog7.fc2.com/blog-entry-657.html c_printf $ unsafePerformIO $ newCString "Hello,world!\n" -- => Hello,world! -- newCString は解放が必要らしい。 -- withCString を使うと自動解放してくれるらしい。 -- 参考:オレのメモ -- http://bw28.blog5.fc2.com/?tag=Haskell withCString "Hello,world!\n" c_printf -- => Hello,world! newCString "Hello,world!\n" >>= c_printf -- => Hello,world! str <- newCString "Hello,world!\n" putStrLn $ show $ c_strlen str -- => 13 putStrLn $ show $ c_sin 40.0 -- => 0.7451131604793488 form <- newCString "Sin 40.0 = %f\n" c_print2 form (c_sin 40.0) -- => Sin 40.0 = 0.745113
Haskell の文字列はListですし、Cの文字列はヌル終端のchar型配列ですから、どうやって値のやりとりをするかという問題があります。
C の関数はreturn で値を返さずにポインタを引数として受け取り文字列や構造体の実態を副作用として処理するものがほとんど。それをラップする関数を書かなくてはならないのかも知れません。