GHC - 没有(Monad Ptr)的实例

时间:2012-11-09 09:54:30

标签: haskell

我是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 }

2 个答案:

答案 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