[英]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的內容。 遇到第一個錯誤時,編譯器可以停止類型檢查,但沒有。 現在,在Ptr
是Monad
的假設下,繼續進行進一步的類型檢查。 因此,在該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.