From the department of “It’s obvious when you know how”. I’d finally got around to working on this issue on Haskerdeux and I’d consolidated the duplicate Curl post requests into one function and had this working code:
curlpost [todays_date, curlpostdata, apiurl, okresponse, username, password] number = withCurlDo $ do
tdsf <- curlget [todays_date, username, password]
let itemid = Main.id $ tdsf!!(read (fromJust number)::Int)
let curlpostfields = if isJust number
then CurlPostFields ["todo_item["++(show itemid)++"?]"++curlpostdata]
else CurlPostFields ["todo_item[todo]="++curlpostdata, "todo_item[do_on]="++todays_date]
But I only wanted to do the tdsf
and let itemid
bits if needed. When I had my three separate (practically duplicate) Curl post requests I could just omit this bit for the function in question, but now I needed some way to handle it conditionally. I had hoped I could do something like this:
curlpost [todays_date, curlpostdata, apiurl, okresponse, username, password] number = withCurlDo $ do
let curlpostfields = if isJust number
then CurlPostFields ["todo_item["++(show itemid)++"?]"++curlpostdata]
else CurlPostFields ["todo_item[todo]="++curlpostdata, "todo_item[do_on]="++todays_date]
where itemid <- do
tdsf <- curlget [todays_date, username, password]
return itemid = Main.id $ tdsf!!(read (fromJust number)::Int)
But that doesn’t work and just gives a parse error on input `<-'
for the where itemid
line. I probably also tried things like:
curlpost [todays_date, curlpostdata, apiurl, okresponse, username, password] number = withCurlDo $ do
let curlpostfields = if isJust number
then do
tdsf <- curlget [todays_date, username, password]
itemid = Main.id $ tdsf!!(read (fromJust number)::Int)
return $ CurlPostFields ["todo_item["++(show itemid)++"?]"++curlpostdata]
else return $ CurlPostFields ["todo_item[todo]="++curlpostdata, "todo_item[do_on]="++todays_date]
But that gets you:
Couldn't match expected type `CurlOption'
against inferred type `IO CurlOption'
In the expression: curlpostfields
Which is obvious really as return
is an IO type. But I was desperate and clutching at straws. However, thanks to this Stackoverflow question I found out you can do this:
curlpost [todays_date, curlpostdata, apiurl, okresponse, username, password] number = withCurlDo $ do
curlpostfields <- if isJust number
then do
tdsf <- curlget [todays_date, username, password]
let itemid = Main.id $ tdsf!!(read (fromJust number)::Int)
return $ CurlPostFields ["todo_item["++(show itemid)++"?]"++curlpostdata]
else return $ CurlPostFields ["todo_item[todo]="++curlpostdata, "todo_item[do_on]="++todays_date]
Problem solved. I had no idea you could bind if statements in that way. It now seems a shame the where
statement option I tried didn’t work as that is along the same lines as this binding of the if
statement and is a bit more concise.