다른 rigid 타입 에러 에러 질문에 대한 많은 답을 조사했습니다; 그러나 아, 내 지식에 대한 그들 중 누구도 내 경우에 적용되지 않습니다. 그래서 나는 또 다른 질문을 할 것이다.또 다른 하스켈 리지드 타입 변수 에러
module MultipartMIMEParser where
import Control.Applicative ((<$>), (<*>), (<*))
import Text.ParserCombinators.Parsec hiding (Line)
data Header = Header { hName :: String
, hValue :: String
, hAddl :: [(String,String)] } deriving (Eq, Show)
data Content a = Content a | Posts [Post a] deriving (Eq, Show)
data Post a = Post { pHeaders :: [Header]
, pContent :: [Content a] } deriving (Eq, Show)
post :: Parser (Post a)
post = do
hs <- headers
c <- case boundary hs of
"" -> content >>= \s->return [s]
b -> newline >> (string b) >> newline >>
manyTill content (string b)
return $ Post { pHeaders=hs, pContent=c }
boundary hs = case lookup "boundary" $ concatMap hAddl hs of
Just b -> "--" ++ b
Nothing -> ""
-- TODO: lookup "boundary" needs to be case-insensitive.
content :: Parser (Content a)
content = do
xs <- manyTill line blankField
return $ Content $ unlines xs -- N.b. This is the line the error message refers to.
where line = manyTill anyChar newline
headers :: Parser [Header]
headers = manyTill header blankField
blankField = newline
header :: Parser Header
header =
Header <$> fieldName <* string ":"
<*> fieldValue <* optional (try newline)
<*> nameValuePairs
where fieldName = many $ noneOf ":"
fieldValue = spaces >> many (noneOf "\r\n;")
nameValuePairs = option [] $ many nameValuePair
nameValuePair :: Parser (String,String)
nameValuePair = do
try $ do n <- name
v <- value
return $ (n,v)
name :: Parser String
name = string ";" >> spaces >> many (noneOf "=")
value :: Parser String
value = string "=" >> between quote quote (many (noneOf "\r\n;\""))
where quote = string "\""
그리고 오류 메시지 :
가 여기에 관련 코드의
내가 본 바로는Couldn't match type `a' with `String'
`a' is a rigid type variable bound by
the type signature for content :: Parser (Content a)
at MultipartMIMEParser.hs:(See comment in code.)
Expected type: Text.Parsec.Prim.ParsecT
String() Data.Functor.Identity.Identity (Content a)
Actual type: Text.Parsec.Prim.ParsecT
String() Data.Functor.Identity.Identity (Content String)
Relevant bindings include
content :: Parser (Content a)
(bound at MultipartMIMEParser.hs:72:1)
In a stmt of a 'do' block: return $ Content $ unlines xs
In the expression:
do { xs <- manyTill line blankField;
return $ Content $ unlines xs }
In an equation for `content':
content
= do { xs <- manyTill line blankField;
return $ Content $ unlines xs }
where
line = manyTill anyChar newline
, 문제는 내가 명시 적으로 unlines xs
를 사용하여 String
를 반환하고있어 것입니다 형식 서명에 a
의 일반 특성이 적용되지 않습니다. 나는 이해에 가깝습니까?
아마도이 파서가 String
이외의 다른 유형에 사용되기 때문에 을 generic으로 선언했습니다. 아마도 저는 조기에 추상화하고 있습니다. 내 모든 a
을 제거하려고했지만, 더 많은 컴파일 오류가 발생하기 시작했습니다. 이 시점에서 합리적이라면 제네릭 방식을 고수하고 싶습니다.
코드에서 내가 뭘 하려는지 분명합니까? 그렇다면 최선의 방법에 대한 제안 사항이 있습니까? , 여기 당신이 String ~ a
있을 것
어떤 줄이 오류입니까? SSCCE를 만들 수 있습니까? – Shoe
코드에서 오류가있는 행을 주석으로 기록했습니다. 실제 모듈에서 71:12 줄입니다. 그러나 모든 코드를 포함하지 않았으므로 여기서는 쓸모가 없습니다. 그 줄은'content $ '에'return $ Content $ unlines xs'입니다. –
SSCCE는 어떻습니까? – Shoe