繁体   English   中英

GHC-(Monad Ptr)没有实例

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

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

现在修复

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(带有多个语句),因此对于某些Monad m和某些a类型,结果类型必须具有ma形式。

该声明的结果类型Ptr CChar形式相匹配ma用- m = Ptr, a = CChar -所以剩下的就是找到/核实Monad类型构造的实例Ptr 没有范围,因此

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

第一个报告的错误。

第二个错误来自分析do-block的内容。 遇到第一个错误时,编译器可以停止类型检查,但没有。 现在,在PtrMonad的假设下,继续进行进一步的类型检查。 因此,在该do-block中,每个<-右边的表达式(在分解后成为(>>=) :: Monad m => ma -> (a -> mb) -> mb a- (>>=) :: Monad m => ma -> (a -> mb) -> mb的第一个参数(>>=) :: Monad m => ma -> (a -> mb) -> mb ),必须具有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 - Ptr不匹配)。

在执行IO作业时,必须使用monadic函数:

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

暂无
暂无

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

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