简体   繁体   English

GHC-(Monad Ptr)没有实例

[英]GHC - No instance for (Monad Ptr)

I'm new to haskell and I'm attempting to write my first haskell C library. 我是Haskell的新手,正在尝试编写我的第一个haskell C库。 This is my first time using the Foreign.C module. 这是我第一次使用Foreign.C模块。 I'm getting lost in examples and have become stuck. 我迷失在例子中,陷入困境。 This is what I have come up with so far: 到目前为止,这是我想出的:

{-# 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

I get the following error: 我收到以下错误:

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 }

Now that the fix 现在修复

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

is clarified, let us find out how the error messages come to be: 澄清之后,让我们找出错误消息是如何产生的:

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

The declared result type of grep is CString , which is a type synonym for Ptr CChar . grep的声明结果类型为CString ,这是Ptr CChar的类型同义词。 The right hand side of the definition is a do-block (with more than one statement), so the result type must have the form ma for some Monad m and some type a . 该定义的右侧是一个do-block(带有多个语句),因此对于某些Monad m和某些a类型,结果类型必须具有ma形式。

The declared result type Ptr CChar matches the form ma - with m = Ptr, a = CChar - and so what remains is to find/verify the Monad instance of the type constructor Ptr . 该声明的结果类型Ptr CChar形式相匹配ma用- m = Ptr, a = CChar -所以剩下的就是找到/核实Monad类型构造的实例Ptr There is none in scope, hence 没有范围,因此

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

the first reported error. 第一个报告的错误。

The second error comes from analysing the contents of the do-block. 第二个错误来自分析do-block的内容。 The compiler could have stopped type-checking upon encountering the first error, but didn't. 遇到第一个错误时,编译器可以停止类型检查,但没有。 Now the further type checking continues under the assumption that Ptr were a Monad . 现在,在PtrMonad的假设下,继续进行进一步的类型检查。 So in that do-block, every expression on the right of a <- (which, after desugaring becomes the first argument of a (>>=) :: Monad m => ma -> (a -> mb) -> mb ), must have type Ptr sometype . 因此,在该do-block中,每个<-右边的表达式(在分解后成为(>>=) :: Monad m => ma -> (a -> mb) -> mb a- (>>=) :: Monad m => ma -> (a -> mb) -> mb的第一个参数(>>=) :: Monad m => ma -> (a -> mb) -> mb ),必须具有Ptr sometype类型。 But peekCString :: CString -> IO String , thus 但是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 }

If the compiler continued, it would give the same type error for the second peekCString line, and finally a 如果编译器继续,它将在第二个peekCString行中给出相同的类型错误,最后是

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

for the wrongly typed argument of newCString (plus another IO - Ptr mismatch). 用于newCString类型错误的参数(加上另一个IO - Ptr不匹配)。

You must use a monadic function as you are doing IO stuff: 在执行IO作业时,必须使用monadic函数:

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

Also adapt your export clause: 还要修改您的导出条款:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM