无法定义新类型

时间:2011-02-22 07:59:17

标签: haskell mongodb

好的,所以这是我目前的代码:

import Database.MongoDB
import System.IO
import System.Environment
import Data.UString

data Project = Project { name :: String , desc :: String
                       , category :: String , priority :: Int
                       , repeating :: Bool , done :: Bool } deriving (Show)

data Command m = Save ((DbAccess m) => (Collection -> Document -> m ()))

main = do
  pool <- newConnPool 1 $ host "127.0.0.1"
  (command:args) <- getArgs
  let add = Save $ save (u "projects") [(u "name") =: (u $ Prelude.concat args)]
--  let remove = delete (select [(u "name") =: (u $ Prelude.concat args)] (u "projects"))
  let update = Save $ save (u "projects") [(u "name") =: (u $ Prelude.concat args)]
  let commands = [("add", add),("update", update)]
  let (Just (Save action)) = Prelude.lookup command commands
  db <- access safe Master pool $ use (Database (u "test")) action
  print db

我的基本问题是用户命令的三种可能结果是添加,更新或删除(我正在搞乱MongoDB。)

调用脚本的基本语法是./script {add | update | remove}项目名称在这里

添加和更新具有相同的返回类型,但删除具有不同的返回类型,并且由于它们具有不同的类型签名,因此haskell的类型检查不接受它。我想我必须制作一种新的类型来封装两种可能性,正如我上面尝试过的那样,但我没有得到任何结论。我对haskell和编程也很新,所以请原谅凌乱的代码和可能的noobish问题。

2 个答案:

答案 0 :(得分:1)

也许你可以data Command2有两个结构,比如Save1Save2。第一个封装添加/更新,另一个删除。

然后您需要应用的一些更改是这样的:

let commands = [("add", Save1 add),("update", Save1 update), ("remove", Save2 remove)]

而不是use你可以定义这样的东西:

use2 db (Save1 action)  = use db action
use2 db (Save2 action)  = use db action

要使一切顺利,您还需要将查找更改为此。

let (Just action) = Prelude.lookup command commands

请注意,我现在删除了Save模式匹配器。

我希望这会有所帮助。 :)

答案 1 :(得分:1)

我不明白为什么你说remove有不同的类型。 savedelete有不同的类型,但在应用参数后,它们都返回DbAccess m => m ()

import Database.MongoDB
import System.Environment


commands :: DbAccess m => [String] -> [(String, m ())]
commands args = [("add", add),("update", update),("remove",remove)]
  where
    uargs = u $ Prelude.concat args
    add    = save (u "projects") [u "name" =: uargs]
    update = save (u "projects") [u "name" =: uargs]
    remove = delete $ select [u "name" =: uargs] (u "projects")


main = do
  pool <- newConnPool 1 $ host "127.0.0.1"
  (command:args) <- getArgs
  let (Just action) = Prelude.lookup command $ commands args
  db <- access safe Master pool $ use (Database (u "test")) action
  print db