簡體   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