Reputation: 2926
ok, so here's my current code:
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
My basic problem is that the three possible outcomes for the user's command are either add, update, or remove (I'm messing around with MongoDB.)
Basic syntax for calling the script is ./script {add|update|remove} project name goes here
Add and update have the same return type, but remove has a different one, and since they have different type signatures, haskell's type checking isn't accepting it. I figured I'd have to make a new type to encapsulate both possibilities, as I kind of tried to do above, but I'm not getting anywhere. I'm also very new to haskell and programming in general, so excuse the messy code and possibly noobish question.
Upvotes: 1
Views: 270
Reputation: 12908
I don't understand why you say that remove
has different type. save
and delete
have different types, but after applying arguments they both return 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
Upvotes: 1
Reputation: 10557
Maybe you could have data Command2
with two constructs, say Save1
and Save2
. The first encapsulates add/update and the other remove.
Some changes you then need to apply is something like this:
let commands = [("add", Save1 add),("update", Save1 update), ("remove", Save2 remove)]
And instead of use
you can maybe define something like this:
use2 db (Save1 action) = use db action
use2 db (Save2 action) = use db action
For everything to work you would also need to change the lookup to this.
let (Just action) = Prelude.lookup command commands
Note that I removed Save
pattern matcher now.
I hope this helps. :)
Upvotes: 1