인터페이스는 존재할 수도 있고 존재하지 않을 수도있는 유형의 값을 구성하고 해체 할 수 있습니다 (약!). 불행하게도, HaXml은 타입에 대해 Data
인스턴스를 가지고 있지 않으며 존재하지 않을 수도있는 타입을 참조 할 수 없기 때문에이를 정의 할 수 없으므로 Template Haskell에 의지해야합니다.
다음 모듈 수출 qnameCompat
가 : 템플릿 하스켈을 사용하여 최상위 수준에 접합 할 때 N
이있는 경우
{-# LANGUAGE TemplateHaskell #-}
module HaXmlCompat (qnameCompat) where
import Language.Haskell.TH
qnameCompat :: Q [Dec]
qnameCompat = do
mi <- maybeReify "N"
case mi of
Nothing -> sequence [
tySynD (mkName "QName") [] [t| String |],
valD [p| toQName |] (normalB [| id |]) [],
valD [p| fromQName |] (normalB [| Just |]) []]
Just (DataConI n _ _ _) -> do
s <- newName "s"
sequence [
valD [p| toQName |] (normalB (conE n)) [],
funD (mkName "fromQName") [
clause [conP n [varP s]] (normalB (appE [| Just |] (varE s))) [],
clause [ [p| _ |] ] (normalB [| Nothing |]) []]]
Just i -> fail $
"N exists, but isn't the sort of thing I expected: " ++ show i
maybeReify :: String -> Q (Maybe Info)
maybeReify = recover (return Nothing) . fmap Just . reify . mkName
, qnameCompat
가 확인합니다. 그렇지 않은 경우
toQName = N
fromQName (N s) = Just s
fromQName _ = Nothing
, 다음이 생성됩니다 : 이제
type QName = String
toQName = id
fromQName = Just
만들고 Element
의를 해체 할 수 있습니다, 예를 들어, 만약 그렇다면, 다음과 같은 코드를 생성 ViewPatterns 확장을 사용 :
myElt :: String -> Element i
myElt = Elem (toQName "elemName") [] []
eltName :: Element i -> String
eltName (Elem (fromQName -> Just n) _ _) = n
ViewPatterns하는 것은 물론, 필수 편리하지만되지 않습니다 : 그냥 잘 작동합니다 fromQName
의 결과에 대한 일반적인 패턴 매칭을 사용.
는
가 얼마나 심각한 인터페이스 변화가있다 (이 아이디어는 무엇
maybeReify
및 다른 유용한 유틸리티를 포함하는의 notcpp package을 개발하기 위해 저를 인도된다)? 어떤 변화가 있습니까? 템플릿 haskell이 무엇인지에 따라 당신을 구출 할 수도 있습니다. –@benmachine 유일하게 진짜 변화는'Element' 생성자가 이제'data QName = N String | '문자열'대신에 '뭔가를 말하지 말아요'라고 말하면됩니다. 'Setup.hs' 파일은'Element' 생성자를 함수 (항상 리터럴'String'과 함께)와 패턴 매칭 (때때로 리터럴'String'과 때로는 catch-all 가변 패턴으로)으로 사용합니다. –
'toQName'과'fromQName' 함수가 있다면'QName'이 존재할 때'toQName = N'과'fromQName'은'Ns'를'Just s' (그리고 다른 것은'Nothing '), 반면에'QName'이 존재하지 않으면'toQName = id'와'fromQName = Just'입니까? 그러면 뷰 패턴으로 원하는 것을 할 수있을 것입니다. 나는'toQName'과'fromQName'이 템플릿 haskell로 정의 될 수 있다고 생각합니다. 내 [notcpp 패키지] (http://hackage.haskell.org/package/notcpp) –