2014-07-11 6 views
2

개체 배열을 사용하여 json을 받아 들일 수있는 yesod 처리기가 있습니다. 모든 개체를 데이터베이스에 삽입하고 싶습니다.나는 어떻게 aeson 파싱 된 엔티티 배열의 타입을 인식 할 수 있도록 yesod-persistent를 얻습니까?

newtype NodeList = NodeList [Node] 

instance FromJSON NodeList where 
    parseJSON (Object o) = NodeList <$> o .: "nodes" 
    parseJSON _ = mzero 

postMoreNodesR :: Handler() 
postMoreNodesR = do 
     nodes::NodeList <- requireJsonBody 
     runDB $ mapM_ insert nodes 
     return() 

하지만 어떻게하면 내 엔티티 유형을 인식하지 못합니다. (비록 같은 모듈에있는 다른 POST와 GET 처리기가 훌륭하게 작동한다.) 나는 꽤 가깝다고 말할 수는 있지만, "a0"은 내가 선언 한 타입이 아니기 때문에 무엇을해야할지 모른다. 여기에 오류가 있습니다 :

Handler/Node.hs:46:30: 
    Couldn't match expected type `[a0]' with actual type `NodeList' 
    In the second argument of `mapM_', namely `nodes' 
    In the second argument of `($)', namely `mapM_ insert nodes' 
    In a stmt of a 'do' block: runDB $ mapM_ insert nodes 

답변

3

당신은 바인딩에 직접 패턴 일치 작업도 수행 할 수 있습니다이뿐만 아니라 유형 약어에 대한 필요성을 제거

postMoreNodesR :: Handler() 
postMoreNodesR = do 
    NodeList nodes <- requireJsonBody 

    runDB $ mapM_ insert nodes 

    return() 

. 할 일 식 람다에 해제 설탕 때문에

그것은 작동 :

requireJsonBody >>= \NodeList nodes -> runDB -- ... 
+0

더 좋네요! do 블록 안에서 패턴 매치를 할 수 있는지 몰랐다. – nont

+1

그것은 실제로 람다에 당황하지 않습니다. '실패'덕분에 그보다 더 복잡합니다. – Carl

1

나는 그것을 알아 냈습니다! 나는 유형을 따라 나는 newtyped NodeList를에서 노드를 추출하는 도우미 함수가 필요 실현 :

getNodesFromList :: NodeList -> [Node] 
getNodesFromList (NodeList l) = l 

그런 다음 내 핸들러 함수가되었다 :

postMoreNodesR :: Handler() 
postMoreNodesR = do 
     nodes::NodeList <- requireJsonBody 
     runDB $ mapM_ insert $ getNodesFromList nodes 
     return() 

이 물건 정말 클릭하기 시작!

+0

실제로, 하스켈은 자동으로 당신을 위해 그 기능을 생성 할 수 있습니다 : –

+0

'데이터 NodeList를 = NodeList를 {getNodesFromList :: [노드]} ' –