2014-11-02 2 views
1

간단한 유형이 있고 Aeson과 함께 JSON에 직렬화한다고 가정 해 보겠습니다.하스켈에서 매개 변수화 된 유형을 JSON으로 직렬화하는 방법은 무엇입니까?

{-# LANGUAGE DeriveGeneriC#-} 

import Data.Aeson (ToJSON) 
import Data.Aeson (encode) 
import GHC.Generics 

data Spotting = Spotting { 
    state :: String, 
    bird :: String 
} deriving (Show, Generic) 

instance ToJSON Spotting 

는 이제 birdstate 필드에 추가하여, 사용자가 추가/사용자 정의 메타 데이터를 전달 할 수 있도록, 당신이 원하는 말 : 여기에 기본 설정입니다. 조류 서식지의 경우, 이것은 아마도 기온, 조류의 밀도, 조수의 위치 ... 무엇이든 될 수 있습니다. 우리는 사전에 알지 못합니다. 이처럼 구조화 할 것 같은 Twitter API in Haskell 같은 예보고에서

이 보인다 : 나의 이해에서

data Spotting meta = Spotting { 
    state :: String, 
    bird :: String, 
    meta :: meta 
} deriving (Show, Generic) 

instance ToJSON meta => ToJSON (Spotting meta) 

을 지금까지, 이것은 파라미터 화 된 형태입니다. 목표는 이제 해당 객체에서 일부 JSON을 만드는 간단한 방법을 만드는 것입니다. 그래서 우리는 다음과 같은 함수를 정의합니다 :

spotting bird state meta = encode $ Spotting { 
    state = state, 
    bird = bird, 
    meta = meta 
} 

그러나 나는 아직 여기에서 어디로 가야할 지 모르겠습니다. 나는이 같은 그 함수를 호출 할 때 :

record = spotting "Snowy Egret" "California" "low tide" 

그것은 오류가 발생합니다 일어나고 무엇

No instance for (Data.String.IsString meta0) 
    arising from the literal `"low tide"' 
The type variable `meta0' is ambiguous 
Possible fix: add a type signature that fixes these type variable(s) 
Note: there are several potential instances: 
    instance Data.String.IsString 
      aeson-0.7.0.6:Data.Aeson.Types.Internal.Value 
    -- Defined in `aeson-0.7.0.6:Data.Aeson.Types.Internal' 
    instance a ~ Data.ByteString.Internal.ByteString => 
      Data.String.IsString 
      (attoparsec-0.12.1.2:Data.Attoparsec.ByteString.Internal.Parser a) 
    -- Defined in `Data.Attoparsec.ByteString.Char8' 
    instance Data.String.IsString Data.Text.Internal.Text 
    -- Defined in `Data.Text' 
    ...plus five others 
In the third argument of `spotting', namely `"low tide"' 
In the expression: 
    spotting "Snowy Egret" "California" "low tide" 
In an equation for `record': 
    record = spotting "Snowy Egret" "California" "low tide" 

(I 하스켈 그래서 아직도이 물건을 모두 해석하는 방법의 기초를 배우고 새로운 오전) 여기/어떻게하면이 일을 할 수 있니?

record = spotting "Snowy Egret" "California" MyCustomData { 
    tide = "low" 
} 

어떻게 당신이이 작업을 수행 할 :

최종 목표는되지는 이와 같이 meta 필드에 문자열을 전달하지만, 입력 객체 (하지만 어떤 객체가 될 수 있습니다)에있다 하스켈? 당신이 OverloadedStrings이 켜져 있기 때문에 컴파일러가 meta 종류를 확인해야

record = spotting "Snowy Egret" "California" "low tide" 

를 입력하면

+0

'가능한 수정 : 이러한 유형의 변수를 수정하는 유형 서명 추가' – alternative

답변

5

문제는 ....

입니다. encode은 많은 유형의 구문 분석이 가능하기 때문에 컴파일러에게 무엇을 사용해야하는지 알려주지 않습니다. OverloadedStrings없이 "low tide" 명확 String 형이지만, 그것으로, 그것은 String, ByteString

당신이 고정에 두 가지 선택이 ....

Either-

제거 OverloadedStrings 수

또는

형식을 명시 적으로 지정하십시오.

value = "low tide"::String 
record = spotting "Snowy Egret" "California" value 
관련 문제