假設你有一個簡單的類型,並且想用Aeson將它序列化爲JSON。以下是基本設置:如何在Haskell中將參數化類型序列化爲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
現在說你想要的,除了bird
和state
領域,允許用戶在加時賽/自定義元數據傳遞。對於鳥類發現,也許這是氣溫,鳥類的密度,潮汐的位置......可能是任何事情,我們事先不知道。
從看着像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"
它拋出一個錯誤(我是新來的Haskell所以我仍然在學習如何解釋這一切東西的基礎知識)
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"
發生了什麼在這裏/你如何得到這個工作?
的最終目標是,不要在meta
場傳遞一個字符串,而是一個類型的對象(但它可以是任何對象),像這樣的:
record = spotting "Snowy Egret" "California" MyCustomData {
tide = "low"
}
你是怎麼做到這一點哈斯克爾?
'可能的修復:添加一個修復這些類型變量的類型簽名' – alternative 2014-11-02 23:20:25