1

私はhaskellを初めて使用し、最初のhaskellCライブラリを作成しようとしています。Foreign.Cモジュールを使用するのはこれが初めてです。私は例に迷い、行き詰まってしまいました。これは私がこれまでに思いついたものです:

{-# LANGUAGE ForeignFunctionInterface #-}

module Grep where

import GHC.Ptr
import Foreign.C.String
import Data.List (isInfixOf)

grep :: CString -> CString -> CString
grep i s = do
    ii <- peekCString i
    ss <- peekCString s
    g <- newCString (isInfixOf ii ss)
    g 

foreign export ccall grep :: CString -> CString -> CString

次のエラーが発生します。

PS C:\Users\GGuy\Source\haskell> ghc -c -O grep.hs

grep.hs:11:9:
  No instance for (Monad Ptr)
    arising from a do statement
  Possible fix: add an instance declaration for (Monad Ptr)
  In a stmt of a 'do' block: ii <- (peekCString i)
  In the expression:
    do { ii <- (peekCString i);
      ss <- peekCString s;
      g <- newCString (isInfixOf ii ss);
      g }
  In an equation for `grep':
    grep i s
      = do { ii <- (peekCString i);
             ss <- peekCString s;
             g <- newCString (isInfixOf ii ss);
             .... }

grep.hs:11:16:
  Couldn't match expected type `Ptr t0' with actual type `IO String'
  In the return type of a call of `peekCString'
  In a stmt of a 'do' block: ii <- (peekCString i)
  In the expression:
    do { ii <- (peekCString i);
       ss <- peekCString s;
       g <- newCString (isInfixOf ii ss);
       g }
4

2 に答える 2

5

これで修正

grep :: CString -> CString -> IO Bool
grep i s = do
    ii <- peekCString i
    ss <- peekCString s
    return (isInfixOf ii ss)

foreign export ccall grep :: CString -> CString -> IO Bool

エラーメッセージがどのようになるかを調べてみましょう。

grep :: CString -> CString -> CString
grep i s = do
    ii <- peekCString i
    ss <- peekCString s
    g <- newCString (isInfixOf ii ss)
    g

の宣言された結果の型はgrepですCString。これは の型シノニムですPtr CChar。定義の右側は do ブロック (複数のステートメントを含む) であるため、結果の型はm asomeMonad mおよび some typeの形式である必要がありaます。

宣言された結果の型Ptr CCharはフォームm a- with - と一致するため、残っているのは型コンストラクターのインスタンスm = Ptr, a = CCharを検索/検証することです。スコープには何もないため、MonadPtr

grep.hs:11:9:
  No instance for (Monad Ptr)              -- quite
    arising from a do statement            -- right
  Possible fix: add an instance declaration for (Monad Ptr)    -- Umm, no, not really

最初に報告されたエラー。

2 番目のエラーは、do ブロックの内容を分析した結果です。コンパイラは、最初のエラーが発生したときに型チェックを停止できましたが、停止しませんでした。これで、PtrMonad. したがって、その do ブロックでは、 a の右側にあるすべての式<-(脱糖後は a の最初の引数に(>>=) :: Monad m => m a -> (a -> mb) -> m bなります) は type を持たなければなりませんPtr sometype。しかしpeekCString :: CString -> IO String、こうして

grep.hs:11:16:
  Couldn't match expected type `Ptr t0' with actual type `IO String'
  In the return type of a call of `peekCString'
  In a stmt of a 'do' block: ii <- (peekCString i)
  In the expression:
    do { ii <- (peekCString i);
       ss <- peekCString s;
       g <- newCString (isInfixOf ii ss);
       g }

コンパイラが続行すると、2peekCString行目で同じ型のエラーが発生し、最後に

Couldn't match type `Bool' with `[Char]'
Expected type: String
  Actual type: Bool
In the first argument of `newCString', namely ...

newCString(さらに別のIO-Ptr不一致)の間違って型付けされた引数に対して。

于 2012-11-09T13:55:20.950 に答える
2

IO を行っているため、モナド関数を使用する必要があります。

grep :: CString -> CString -> IO CString
grep i s = do
    ii <- peekCString i
    ss <- peekCString s
    newCString (isInfixOf ii ss)

また、エクスポート句を調整します。

foreign export ccall grep :: CString -> CString -> IO CString
于 2012-11-09T10:15:57.417 に答える