我是haskell的新手,我正在尝试编写我的第一个haskell C库。这是我第一次使用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 }
答案 0 :(得分: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-block(带有多个语句),因此结果类型的某些m a
和某些类型Monad m
的格式必须为a
。< / p>
声明的结果类型Ptr CChar
匹配表单m a
- 与m = Ptr, a = CChar
- 所以剩下的就是查找/验证类型构造函数{Monad
的实例1}}。范围内没有,因此
Ptr
第一次报告错误。
第二个错误来自分析do-block的内容。编译器可能在遇到第一个错误时停止了类型检查,但没有。现在,在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
为Ptr
的假设下,继续进行进一步的类型检查。所以在那个do-block中,Monad
右边的每个表达式(在desugaring成为<-
的第一个参数之后)必须具有类型(>>=) :: Monad m => m a -> (a -> mb) -> m b
。但是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 }
行提供相同的类型错误,最后一个
peekCString
错误输入的Couldn't match type `Bool' with `[Char]'
Expected type: String
Actual type: Bool
In the first argument of `newCString', namely ...
参数(加上另一个newCString
- IO
不匹配)。
答案 1 :(得分:2)
你必须使用monadic函数,因为你在做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