<div dir="ltr"><div style>I am writing a stop-motion capture application using AngularJS and it's going OK. I was inspired to do so after installing "IPCamera" on my phone and Sony tablet. A typical IPCamera session lives on an internal address like this, this example will turn on the LED on the camera:</div>
<div style><br></div><div style> <a href="http://192.168.0.5:8080/enabletorch">http://192.168.0.5:8080/enabletorch</a></div><div style><br></div><div style>Just because I can (or so I thought), I decided to write a tiny little FastCGI application in Haskell to act as a proxy using the PATH_INFO variable. This means that in to my Javascript code I have this code in a service file:</div>
<div style><br></div><div style><div><font face="courier new, monospace">angular.module('stomoServices', ['ngResource']).</font></div><div><font face="courier new, monospace"> factory(</font></div><div>
<font face="courier new, monospace"><span class="" style="white-space:pre">        </span>'IPCamera',</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>function($resource, urlIPCameraAPI) {</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span> return $resource(</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>urlIPCameraAPI,<br>
</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>{}, {</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span> ledOn: { method: 'GET', params: {featureReq: 'enabletorch' }},</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span> ledOff: { method: 'GET', params: {featureReq: 'disabletorch' }},</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span> focusOn: { method: 'GET', params: {featureReq: 'focus' }},</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span> focusOff: { method: 'GET', params: {featureReq: 'nofocus'}}</font></div><div><font face="courier new, monospace"><span class="" style="white-space:pre">                </span>});</font></div>
<div><font face="courier new, monospace"><span class="" style="white-space:pre">        </span>});</font></div><div><br></div><div style>and I then issue commands like "IPCamera.ledOn()" etc. All very nice except that it doesn't work yet because I can't get the worlds seemingly simplest CGI application to compile yet! Here is the code that I have, it could be "cleared up" but this is what I have so far:</div>
<div><br></div></div><div><font face="courier new, monospace">main :: IO ()</font></div><div><font face="courier new, monospace">main = runFastCGI . handleErrors $ do</font></div><div><font face="courier new, monospace"> command <- getVar "PATH_INFO"</font></div>
<div><font face="courier new, monospace"> case command of</font></div><div><font face="courier new, monospace"> Nothing -></font></div><div><font face="courier new, monospace"> outputError 400 "Missing IPCamera instruction (PATH_INFO)" []</font></div>
<div><font face="courier new, monospace"> Just cmd -></font></div><div><font face="courier new, monospace"> ipCamExec (tail cmd) >> output "OK" -- tail drops the "/"</font></div><div>
<font face="courier new, monospace"> where</font></div>
<div><font face="courier new, monospace"> ipCamExec :: String -> IO ()</font></div><div><font face="courier new, monospace"> ipCamExec url = do</font></div><div><font face="courier new, monospace"> simpleHTTP (getRequest url) -- don't want or need response.</font></div>
<div><font face="courier new, monospace"> return () -- to match the return type or so I thought.</font></div><div><br></div><div style>and the error message I cannot seem to understand as it fills me with monadic fear which I can't get out of:</div>
<div style><br></div><div><div><font face="courier new, monospace">ipcamera.hs:16:7:</font></div><div><font face="courier new, monospace"> Couldn't match expected type `CGIT IO a0' with actual type `IO ()'</font></div>
<div><font face="courier new, monospace"> In the return type of a call of `ipCamExec'</font></div><div><font face="courier new, monospace"> In the first argument of `(>>)', namely `ipCamExec (tail cmd)'</font></div>
<div><font face="courier new, monospace"> In the expression: ipCamExec (tail cmd) >> output "OK"</font></div></div><div><br></div><div style>Please could some kind souls explain to me in simple terms just what is going on and why I am close to tears right now? I have read the definitions of CGIResult and CGI and they leave me cold. I am trying to understand monads more but at times like this I once again realise what a complete rank beginner I am!</div>
<div style><br></div><div style>Thanks.</div><div style>Sean.</div><div style><br></div></div>