18:32:55 <aleksejs_> Hi
18:36:22 <stepkut> hi
18:41:08 <aleksejs_> I have type q0 -> IO blah, how do I get blah?
18:41:31 <frozencemetery> that's not a good way to think about it
18:41:41 <frozencemetery> the short answer is that you don't
18:41:54 <frozencemetery> the slightly longer answer is that you want to perform operations on blah within the IO monad
18:44:29 <aleksejs_> ok, probably I asked incorrectly
18:46:24 <aleksejs_> I have this route rule: dir "comment"   $  method POST >> (addComment conn), it is "q0 -> IO GHC.Int.Int64", but I need "Response"
18:50:13 <stepkut> addComment takes another argument?
18:50:37 <aleksejs_> yes
18:51:09 <stepkut> that is.. it takes two arguments?
18:51:27 <aleksejs_> addCommend conn comment = do ...
18:51:35 <stepkut> you only passed it one argument..
19:07:28 <aleksejs_> now I have:
19:07:28 <aleksejs_>  Couldn't match expected type `[Response]'
19:07:28 <aleksejs_>                 with actual type `Response'
19:08:01 <aleksejs_> method POST >> dir "comment" >> fmap toResponse .  resultToJSON (withData (addComment conn)),
19:08:02 <stepkut> seems odd that something would want a list of [Response]
19:08:31 <stepkut> withData passes the extra argument to addComment?
19:09:26 <aleksejs_> withData
19:09:27 <aleksejs_>   :: (Control.Monad.MonadPlus m, HasRqData m, FromData a,
19:09:27 <aleksejs_>       ServerMonad m) =>
19:09:27 <aleksejs_>      (a -> m r) -> m r
19:09:29 <stepkut> you probably want $ instead of . there
19:10:40 <aleksejs_> with $ :
19:10:41 <aleksejs_>     Couldn't match expected type `ServerPartT IO a0'
19:10:41 <aleksejs_>                 with actual type `q0 -> Response'
19:12:10 <stepkut> what is the type of 'addComment' and 'resultToJSON' ?
19:14:17 <aleksejs_> resultToJSON :: (Data.Data.Data a, Functor f) => f a -> f String
19:14:18 <aleksejs_> addComment
19:14:18 <aleksejs_>   :: Database.MySQL.Simple.QueryParams.QueryParams q =>
19:14:18 <aleksejs_>      Database.MySQL.Base.Connection -> t -> q -> IO GHC.Int.Int64
19:15:30 <stepkut> addComment takes three arguments?
19:16:23 <stepkut> you've pass one argument to it (conn), and withData will pass another one, but what about the third argument?
19:17:08 <aleksejs_> hmm, I'm not sure why it shows 3rd argument
19:17:22 <aleksejs_> addComment conn comment = do ..
19:17:45 <stepkut> so, the stuff after the 'do' must be returning a lambda abstraction
19:17:48 <aleksejs_> wait a second
19:18:00 <aleksejs_> yes, you're right
19:18:08 <stepkut> if you add an explicit type to addComment -- then you would get the error in addComment instead of when you call addComment
19:24:54 <aleksejs_> I modified addComment, now it's addComment
19:24:54 <aleksejs_>   :: Database.MySQL.Base.Connection -> t -> IO GHC.Int.Int64
19:27:28 <stepkut> great
19:27:40 <aleksejs_> but still
19:27:41 <stepkut> now you probably get some error because you have IO but need ServerPart ?
19:28:02 <aleksejs_>     Couldn't match expected type `ServerPartT IO a0'
19:28:02 <aleksejs_>                 with actual type `t0 -> Response'
19:28:39 <stepkut> your code looks like this now? method POST >> dir "comment" >> fmap toResponse $  resultToJSON (withData (addComment conn))
19:29:32 <aleksejs_> yes
19:32:06 <stepkut> if you comment out that line, the error goes away?
19:32:32 <aleksejs_> yes
19:32:50 <stepkut> oh
19:33:19 <stepkut> try this: method POST >> dir "comment" $ fmap toResponse $  resultToJSON (withData (addComment conn))
19:34:11 <aleksejs_>     No instances for (Control.Monad.MonadPlus ((->) (IO Response)),
19:34:12 <aleksejs_>                       ServerMonad ((->) (IO Response)))
19:34:12 <aleksejs_>       arising from a use of `method'
19:34:23 <stepkut> try this: method POST >> (dir "comment" $ fmap toResponse $  resultToJSON (withData (addComment conn)))
19:34:59 <aleksejs_>     No instance for (ServerMonad IO)
19:34:59 <aleksejs_>       arising from a use of `method'
19:35:01 <aleksejs_> :)
19:35:03 <stepkut> yeah
19:35:21 <stepkut> so, that is because addComment is IO, and you never lift it to ServerPart
19:35:29 <stepkut> try this: method POST >> (dir "comment" $ fmap toResponse $  resultToJSON (withData (liftIO $ addComment conn))
19:35:48 <stepkut> 'dir' is annoying
19:36:26 <stepkut> it has the type, "dir :: (MonadPlus m, ServerMonad m) => String -> m a -> m a"
19:36:33 <aleksejs_>     Couldn't match expected type `IO a0'
19:36:33 <aleksejs_>                 with actual type `t0 -> IO GHC.Int.Int64'
19:36:44 <stepkut> try this: method POST >> (dir "comment" $ fmap toResponse $  resultToJSON (withData (liftIO . addComment conn))
19:37:12 <stepkut> but it is very tempting to use 'dir' as if it had the type,  dir :: (MonadPlus m, ServerMonad m) => String -> m ()
19:37:29 <aleksejs_>     Ambiguous type variable `a0' in the constraint:
19:37:29 <aleksejs_>       (FromData a0) arising from a use of `withData'
19:37:29 <aleksejs_> this is much better
19:37:45 <stepkut> yeah, that is because your type sig for addComment is too general
19:37:50 <aleksejs_> mhm
19:38:48 <stepkut> also, trying to write all this on one line just makes it harder to read and understand IMO
19:40:18 <aleksejs_> yes, I'll try to split it to smaller chunks when it will work
19:40:37 <aleksejs_> these routing rules look ugly now
19:41:09 <stepkut> indeed.. if you rewrite them to look pretty, they will also make more sense :)
19:47:18 <aleksejs_> hmm, the problem is that I have addComment in one file and dbAdd in another. adddComment calls dbAdd. I did it to get an abstraction from specific DBMS
19:48:31 <aleksejs_> so, I can't add type signature to addComment because I need to import MySQL there, and then this abstraction loses sense
19:49:48 <stepkut> at some point you need to tell withData what the type of the value you are trying to extract is
19:50:37 <stepkut> maybe something like: method POST >> (dir "comment" $ fmap toResponse $  resultToJSON (withData (\x -> liftIO $ addComment conn (x :: SomeType))))
19:53:05 <aleksejs_> could it be FromData?
19:54:40 <stepkut> FromData is class not a type..
19:55:22 <aleksejs_> yes..
19:58:03 <stepkut> in order to know with fromData instance to call the compile must have some way to determine the Type you are trying to convert to
20:01:14 <aleksejs_> so I need to define data structure for this?
20:04:46 <stepkut> I don't really know what you are trying to do
20:11:06 <stepkut> but currently your code is trynig to read the submitted data and convert it to a Haskell value, yet you do not seem to have enough information present to determine the type of the Haskell value you want to convert it to.. if you don't want to convert the data to haskell value.. then don't use withData I guess
20:17:01 <aleksejs_> it seems that it works now :)
20:18:01 <aleksejs_> I've defined a data structure Comment, then added FromData instance for it and added (x :: Comment) in route
20:18:26 <aleksejs_> not sure it wil actually write data to DB, but at least it compiles :)
20:19:44 <aleksejs_> thanks for help :)
20:33:53 <stepkut> no problem
21:01:19 <aleksejs_> are you still here?
21:02:22 <aleksejs_> nvm :)
21:38:12 <aleksejs_> Could you help me again?
22:39:57 <stepkut> sure
22:52:51 <aleksejs_> sorry, I've already figured that out
22:53:06 <aleksejs_> and made routes a little bit cleaner
22:54:01 <aleksejs_> http://vpaste.net/PffKF
22:54:18 <aleksejs_> butI'm sure there enough space for improvement
22:55:31 <stepkut> 3spiffy