2016-02-28 58 views
0

什麼是字符串"[\"id\"=:5977, \"brandId\"=:87]"轉換爲場MongoDB的["id"=:5977, "brandId"=:87]哈斯克爾:字符串轉換爲現場MongoDB的

,甚至更好,如果我有一個數據類型

data Body = Body 
{ body_id :: int 
    brandId :: Int } deriving (Show) 

給予最好的辦法

Body {body_id = 5977, brandId = 87}

什麼是將其轉換爲

的最佳方法

["id"=:5977, "brandId"=:87]

謝謝。

+1

爲什麼你的意思是「對於mongodb」?你想轉換爲json嗎?如果是,那就是aeson包。更多信息可以幫助。 – sinelaw

+0

@sinelaw Database.MongoDB的字段語法如上所述。我不知道 ;他們的例子是「access pipe master」dbname「$ insert」collection「[」author「=:」Mike「]'。所以我想弄清楚如何轉換數據類型以適應該字段格式。 – matthias

回答

4

如果我理解正確,您正在使用hackage: mongoDB與數據庫交互。

所以,我們要做的唯一事情是一個Haskell值轉換爲BSON價值這是hackage: bson提供,特別是在類型類Val

class (Typeable a, Show a, Eq a) => Val a where 

Haskell types of this class correspond to BSON value types 

Minimal complete definition 
val, cast' 

Methods 
val :: a -> Value 
... 
cast' :: Value -> Maybe a 
... 

所以它仍然實現valcast'

但首先我們需要推導出比您擁有的更多屬性:

Body.hs

{-# LANGUAGE DeriveDataTypeable #-} 
{-# LANGUAGE OverloadedStrings #-} 
module Body where 

import Data.Bson 
import Data.Typeable 

data Body = Body { bodyID :: Int 
       , brandID :: Int } 
       deriving (Show,Typeable,Eq) 


instance Val Body where 
    val (Body body brand) = Doc [ "bodyID" := (Int64 $ fromIntegral body) 
           , "brandID" := (Int64 $ fromIntegral brand)] 

    cast' (Doc bson) = case (bson !? "bodyID") of 
          Just (Int64 x) -> 
           case (bson !? "brandID") of 
             Just (Int64 y) -> Just (Body (fromIntegral x) 
                     (fromIntegral y)) 
             Just _ -> Nothing 
             Nothing -> Nothing 
          Just _ -> Nothing 
          Nothing -> Nothing 
    cast' (Array x) = undefined 
    cast' _ = Nothing 

這是一個有點集羣而是簡單。


下面我就給這個東西多一點思考 - 以前cast'真的集羣和Haskell有很好的抽象應該做的更好

val (Body body brand) = Doc [ "bodyID" := (val body) 
           , "brandID" := (val brand)] 
    cast' (Doc bson) = do body <- (bson !? "bodyID") 
         brand <- (bson !? "brandID") 
         Body <$> cast' body <*> cast' brand 

    cast' _ = Nothing 

所以,你真的可以寫這個有點短接受這樣<$> (叫做fmap)和<*>(叫做ap做「正確」的事

另外我用do符號來簡化FY工作,現在用這個

> cast' $ val (Body 30 4) :: Maybe Body 
Just (Body {bodyID = 30, brandID = 4}) 

在你真正需要的註釋:: Maybe Body最後一個例子,否則編譯器無法弄清楚投什麼,你會得到一個Nothing

+0

'fromIntegral'是必須的,因爲Value只知道'Int32'和'Int64',所以你需要將它們轉換 – epsilonhalbe

+0

'cast''的第二個版本是我爲什麼喜歡haskell的原因之一 - 短,優雅和漂亮即使你不懂這門語言也可以理解,即使將它作爲新手來生產也不是小事 – epsilonhalbe

+0

謝謝。我正在學習Haskell,目前發現它確實很難;但像你這樣的人是一個很好的幫助。這很好用。 – matthias