2014-05-16 3 views
0

저는 실제로 haskell을 처음 사용했습니다.XML 문서를 파싱하기위한 하스켈

반환 나는 다음과 같은 오류가 야해 XML 요소

getName :: Content -> Name 
getName (CElem (Elem nme atts cs)) = nme 

의 태그 이름 :이 코드를 실행하려고하면

Expecting one more argument to `Content' 
    In the type signature for `getName': getName :: Content -> Name 

당신은 내가 그것을 해결하기 위해 도와주세요 수 있습니다.

+0

어떤 라이브러리를 사용하고 있습니까? 특정 문제에 대한 자세한 정보를 제공 할 수 있습니까? – bheklilr

+0

HaXML 1.13.3 및 하스켈 컴파일러 GHC7.6.3을 사용하고 있습니다. – user3644664

+0

* 힌트 : * ['Content'] (http://hackage.haskell.org/package/HaXml-1.23.3/docs/Text-XML-HaXml-Types.html#t:Content)는 유형이 아니며, 하지만 형식 * 생성자 *. 오류 메시지에서 알 수 있듯이 하나의 인수를 'Content'에 전달해야합니다. 'Content i'. – fizruk

답변

2

게시 한 코드에 몇 가지 문제가 있습니다.이 코드는 모두 유형을 보면 알 수 있습니다. 여기

data Content i = CElem (Element i) i 
       | CString Bool CharData i 
       | CRef Reference i 
       | CMisc Misc i 
       deriving Show 

data Element i = Elem QName [Attribute] [Content i] deriving (Eq, Show) 

data QName = N Name 
      | QN Namespace Name 
      deriving (Eq,Show) 

data Reference = RefEntity EntityRef 
       | RefChar CharRef 
       deriving (Eq,Show) 
type EntityRef = Name 

가 게시 된 코드에 문제가 있습니다 : 여기 docs에서 관련 유형 정보입니다

  1. Content 종류 * -> *을 가지고 유형, 즉이 Content타입 생성자입니다 type 매개 변수를 인수로 취해 유형을 반환합니다. 당신은 당신의 getName 기능이 서명을해야 의미 함수에 대한 값으로 부분적으로 적용 유형 (Content)를 통과 할 수

    CElem에 귀하의 패턴 일치는 하나 개의 인수를 가지고 있지만
    getName :: Content i -> Name 
    
  2. 당신은 볼 수 있습니다 위 정의에서 두 개의이 걸립니다. 생성자 값 중 하나만 사용하고 있으므로 다른 값을 _으로 바꿀 수 있습니다.

    getName :: Content i -> Name 
    getName (CElem (Elem nme _ _) _) = nme 
    
  3. Elem 생성자의 첫 번째 인수는 QName을 입력 가지고 있지만, 서명은 당신이 유형 Name의 무언가를 반환 할 제안 : 지금까지, 우리는이 있습니다. 즉, nme 만 반환 할 수는 없습니다.

    getName :: Content i -> Name 
    getName (CElem (Elem (N nme) _ _) _) = nme 
    

최종 정의, 당신은 가능성이 논박 패턴 일치로 인해 런타임 오류를 얻을 수 있습니다 컴파일해야하지만 대신, 우리는 N 생성자 다시 패턴 일치하는 이름을 꺼내 필요 . 이는 패턴과 값을 일치 시키려고 시도하지만 패턴을 찾을 수 없음을 의미합니다. 예를 들어 Elem의 첫 번째 인수는 유형QName이지만 QN 생성자를 사용하여 구성 할 수 있습니다. 마찬가지로

getName (CElem (Elem (QN _ nme) _ _) _) = nme 

, 당신은 논박 패턴 일치를 위해 다른 모든 가능성을 고려해야합니다 : 우리가 생성자에 대한 사례를 추가 할 경우 따라서는 더 좋을 것 Elem 생성자가 괜찮습니다; 유형 Element i에는 하나의 생성자 만 있습니다. 유형 Content i에는 여러 생성자가 있습니다. CString 생성자에는 분명히 파생 가능한 값 Name이 없으므로 지금은 무시하겠습니다.

getName (CRef (RefEntity nme) _) = nme 

Reference의 다른 생성자가 이름을 가지고 있지 않은, 그래서 우리는 그것을 무시 : CRef는, 그래서 우리는 그것을 위해 케이스를 추가 할 것입니다 않습니다. CMisc까지 알려 드리겠습니다.

This means that the final definition of `getName` should looks something like this: 

getName :: Content i -> Name 
getName (CElem (Elem (N nme) _ _) _) = nme 
getName (CElem (Elem (QN _ nme) _ _) _) = nme 
getName (CRef (RefEntity nme) _) = nme 
-- maybe add a case for CMisc here 
getName _ = error "Content constructor doesn't have a Name!" 
+0

문제가 해결되었으므로 다른 문제를 해결해 드리겠습니다. 우선, 이것들은 모두 하스켈의 기본적인 기술이며, 더 이상 진행하기 전에 자습서를 읽어야한다는 것을 나타냅니다. (또는 SO에 대해 더 많은 질문을합니다.) 당신은 과다 [여기] (http://stackoverflow.com/questions/1012573/getting-started-with-haskell)를 찾을 수 있습니다. – crockeea

+0

단순함을 제쳐두고, 질문에 거의 눈에 띄지 않는 다른 문제가 있습니다. * 컴파일 *, * 최소 예제 *없이 컴파일 오류를 진단하는 것은 매우 어렵습니다. 예를 들어, 원래 질문에서 'HaXML'을 사용했다는 언급조차하지 않았고 관련 유형 정보를 찾기 위해 검색해야했습니다. import 문을 포함 시키면 (즉, 코드를 컴파일 한 경우) 나중에 답변을 얻는 것이 더 쉬울 것입니다. 좋은 질문 [여기] (http://stackoverflow.com/questions/how-to-ask)에 대한 더 자세한 정보를 찾을 수 있습니다. – crockeea

+0

이 답변이 도움이 되셨다면 옆에있는 체크 표시를 눌러 수락하실 수 있습니다. – crockeea

관련 문제