2016-02-28 38 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