Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://www.haskell.org/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. example of compostion (Rainer Grimm) 2. Re: Any advice on installing gtk2hs (patricklynch) 3. Re: example of compostion (Ozgur Akgun) 4. Re: Any advice on installing gtk2hs (Daniel Fischer) 5. Re: Any advice on installing gtk2hs (Krzysztof Skrz?tnicki) 6. Almost there. Bizzaro problem with libcurl forces kludge that I would like to be rid of. (Michael Litchard) ---------------------------------------------------------------------- Message: 1 Date: Mon, 31 Jan 2011 22:15:18 +0100 From: Rainer Grimm <rai...@grimm-jaud.de> Subject: [Haskell-beginners] example of compostion To: beginners@haskell.org Message-ID: <4d472666.9080...@grimm-jaud.de> Content-Type: text/plain; charset="iso-8859-15" Hello, I'm looking for a good example of function composition. It's very impressive, how concise you can extract information out of a file in Haskell. So I write a short programm, which gets all title words out of a given file sorted by their length. How could the following programm be improved? import Data.Char (isUpper,isLower) import Data.List (sortBy) import Data.Ord (comparing) isTitle word= isFirstUpperCase ( word) && isTailLowerCase ( word ) where isFirstUpperCase= isUpper . head isTailLowerCase= all isLower . tail main = do putStrLn "The name of the input file:" file <- getLine inputString <- readFile file let allTitles= reverse . sortBy (comparing length ) . filter isTitle $ words inputString putStrLn $ show $ take 15 allTitles putStrLn $ show (length allTitles) ++ " titles in " ++ file Thanks in advance, Rainer -- Rainer Grimm rai...@grimm-jaud.de http://www.grimm-jaud.de <javascript:void(0);> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://www.haskell.org/pipermail/beginners/attachments/20110131/e3df3b8d/attachment-0001.htm> ------------------------------ Message: 2 Date: Mon, 31 Jan 2011 17:25:08 -0500 From: "patricklynch" <kmandpjly...@verizon.net> Subject: Re: [Haskell-beginners] Any advice on installing gtk2hs To: <beginners@haskell.org> Message-ID: <77c8062e93bc405990ed69e0b516a...@stsv.com> Content-Type: text/plain; charset="us-ascii" To Aditya Siram ...thanks for writing the procedure in the link in the email below...... ...I got stuck on the command: 'cabal install gtk' ...it gives the following message: Linking: C:\Users\User\AppData\Local\cairo-0.12.043\cairo-0.12\dist\setup\setup.exe ... Cannot find gtk2hsC2hs Please install 'gtk2hs-buildtools' first and check that the install Directory is in your PATH (e.g.. HOME/.cabal/bin) My PATH is C:/Users/User/AppData/Roaming/cabal/bin Should I change my PATH? Good day -----Original Message----- From: patricklynch [mailto:kmandpjly...@verizon.net] Sent: Monday, January 31, 2011 1:55 PM To: 'patricklynch'; beginners@haskell.org Subject: RE: Any advice on installing gtk2hs PS, this was for the Windows installation... -----Original Message----- From: patricklynch [mailto:kmandpjly...@verizon.net] Sent: Monday, January 31, 2011 1:54 PM To: 'beginners@haskell.org' Subject: Any advice on installing gtk2hs Good afternoon, Any advice on installing gtk2hs... I used the instructions at: http://www.haskell.org/haskellwiki/Gtk2Hs and get a bunch of error messages... Thanks... -------------- next part -------------- A non-text attachment was scrubbed... Name: winmail.dat Type: application/ms-tnef Size: 6144 bytes Desc: not available URL: <http://www.haskell.org/pipermail/beginners/attachments/20110131/3c9b09d6/attachment-0001.bin> ------------------------------ Message: 3 Date: Mon, 31 Jan 2011 22:04:59 +0000 From: Ozgur Akgun <ozgurak...@gmail.com> Subject: Re: [Haskell-beginners] example of compostion To: Rainer Grimm <rai...@grimm-jaud.de> Cc: beginners@haskell.org Message-ID: <AANLkTi=v72jz7rebkmhqw9txy8d7y8jt0u3v-ohzj...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" On 31 January 2011 21:15, Rainer Grimm <rai...@grimm-jaud.de> wrote: > isTitle word= > isFirstUpperCase ( word) && isTailLowerCase ( word ) > where isFirstUpperCase= isUpper . head > isTailLowerCase= all isLower . tail > One possible improvement is using pattern matching while defining isTitle. isTitle [] = False -- I suppose? isTitle (x:xs) = isUpper x && all isLower xs -- Ozgur -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://www.haskell.org/pipermail/beginners/attachments/20110131/22056b24/attachment-0001.htm> ------------------------------ Message: 4 Date: Mon, 31 Jan 2011 23:11:50 +0100 From: Daniel Fischer <daniel.is.fisc...@googlemail.com> Subject: Re: [Haskell-beginners] Any advice on installing gtk2hs To: beginners@haskell.org Message-ID: <201101312311.51202.daniel.is.fisc...@googlemail.com> Content-Type: text/plain; charset="utf-8" On Monday 31 January 2011 23:25:08, patricklynch wrote: > To Aditya Siram > > > > ...thanks for writing the procedure in the link in the email below...... > > ...I got stuck on the command: 'cabal install gtk' > > ...it gives the following message: > > > > Linking: > > C:\Users\User\AppData\Local\cairo-0.12.043\cairo-0.12\dist\setup\setup.e >xe > > ... > > Cannot find gtk2hsC2hs > > Please install 'gtk2hs-buildtools' first and check that the install > > Directory is in your PATH (e.g.. HOME/.cabal/bin) > Have you done 'cabal install gtk2hs-buildtools' first? That step is not listed under point 5.1.5, that may be an oversight. If you have, where is gtk2hsC2hs located, is it in C:/Users/User/AppData/Roaming/cabal/bin or elsewhere? > > > My PATH is C:/Users/User/AppData/Roaming/cabal/bin > > Should I change my PATH? > > > > Good day > > ------------------------------ Message: 5 Date: Mon, 31 Jan 2011 23:05:33 +0100 From: Krzysztof Skrz?tnicki <gte...@gmail.com> Subject: Re: [Haskell-beginners] Any advice on installing gtk2hs To: patricklynch <kmandpjly...@verizon.net> Cc: beginners@haskell.org Message-ID: <AANLkTik1u256SFSGoRvvuHFSGrJByzvp=YwDC=xkr...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" > > > Cannot find gtk2hsC2hs > > Please install 'gtk2hs-buildtools' first and check that the install > > Well, did you follow the message with 'cabal install gtk2hs-buildtools' then? Best regards, Krzysztof Skrz?tnicki -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://www.haskell.org/pipermail/beginners/attachments/20110131/8e30b64b/attachment-0001.htm> ------------------------------ Message: 6 Date: Mon, 31 Jan 2011 14:42:30 -0800 From: Michael Litchard <mich...@schmong.org> Subject: [Haskell-beginners] Almost there. Bizzaro problem with libcurl forces kludge that I would like to be rid of. To: beginners@haskell.org Message-ID: <AANLkTinoG0=-bXLr6uerNw-bhYMEmi1zvWvr=n6e+...@mail.gmail.com> Content-Type: text/plain; charset="iso-8859-1" So, I've been writing a http client designed to simulate a session with one of my company's products. The crucial thing we need from this program is a cookie jar. When I began I was doing exploratory code to figure things out about http. I managed to make a cookie jar with my toy code, along with the intermediate steps needed to generate the cookies that represent a session. Then it was time to integrate my experimental toy code into something closer to what production code should look like. This is where bizarro behavior starts to happen. All the intermediate steps appear to be working, as later steps are dependent on earlier steps succeeding. Yet in the end, no cookie jar. We did an strace on the binary and it appears that there seems to be a problem with the reading/writing of the file to be the cookie jar, and we don't know why. The kludge solution is to write a wrapper that calls the program in such a way that I can capture standard error and parse out the cookies. I would hate for things to remain this way. It disturbs me. So, my toy code can create a cookie jar. But what will one day be production code does everything correctly except produce the cookie jar. Included is the entire program, standard error, and strace output. Also, my toy program which succeeds in producing a cookie jar. If anyone wants to take a stab at this that would be peachy. I'm looking for avenues to explore and good questions to ask, as I am out of both. P.S. Thanks to everyone who got me this far. If this is what we end up having to use, it does get the job done. I'm just trying to get rid of my kludge work-around. > {-# LANGUAGE FlexibleContexts #-} > module Main where ------------------------------------------------------------------------------ -- Imports ------------------------------------------------------------------------------ > import Control.Monad > import Control.Monad.Error > import Network.Curl > import System.Environment (getArgs) > import HtmlParsing > import SessionCreator > main :: IO () > main = do > curl <- initCurl > user:pass:_ <- getArgs > resp <- generateResourceHtml curl user pass > > case resp of > Left err -> print err > Right body -> obtainCookies curl body > {-# LANGUAGE FlexibleContexts #-} > module SessionCreator > ( > initCurl, > curlResp, > urlBase, > urlInitial, > urlLogin, > urlLogOut, > urlFlash1, > urlFlash2, > urlLaunch, > urlLaunchTest, > urlQuickCreate, > urlGetResource, > urlShowWebForwards, > respBody, > -- login > resourceOpts, > loginOpts > ) where ------------------------------------------------------------------------------ -- Imports ------------------------------------------------------------------------------ --import qualified Data.ByteString as B > import Network.Curl > import Control.Monad > import Control.Monad.Error > initCurl :: IO Curl > initCurl = do > curl <- initialize > setopts curl curlOpts > return curl > curlOpts :: [CurlOption] > curlOpts = > [ CurlCookieSession True > , CurlCookieJar "cookies.txt" > , CurlCookieFile "cookies2.txt" > , CurlFollowLocation True > , CurlUserAgent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" > , CurlVerbose True > , CurlHeader True > , CurlAutoReferer True > , CurlFailOnError True > ] > --- loginOpts looks like this for now > loginOpts :: String -> String -> [CurlOption] > loginOpts user pass = > [ CurlFailOnError True > , CurlPost True > , CurlNoBody False > , CurlPostFields > [ "_charset_=UTF-8" > , "javaScript=true" > , "username=" ++ user > , "password=" ++ pass > ] > ] > resourceOpts :: [CurlOption] > resourceOpts = > [ CurlHttpHeaders > [ "Accept: text/javascript, text/html, application/xml, text/xml, */*" > , "Accept-Language: en-us,en;q=0.5" > , "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" > , "Keep-Alive: 115" > , "Connection: keep-alive" > , "X-Requested-With: XMLHttpRequest" > , "X-Prototype-Version: 1.6.0.3" > ] > , CurlEncoding "gzip,deflate" > ] > curlResp :: (Error e, MonadError e m, MonadIO m) => > Curl -> URLString -> [CurlOption] -> m String --CurlResponse > curlResp curl url opts = do > resp <- liftIO $ (do_curl_ curl url opts :: IO CurlResponse) > let code = respCurlCode resp > status = respStatus resp > if code /= CurlOK || status /= 200 > then throwError $ strMsg $ "Error: " ++ show code ++ " -- " ++ show status > else return $ respBody resp ------------------------------------------------------------------------------ URLs ------------------------------------------------------------------------------ > (//) :: String -> String -> String > a // b = a ++ "/" ++ b > urlBase :: URLString > urlBase = "https://172.16.1.18" > urlInitial = urlBase // "showLogon.do" > urlLogin = urlBase // "default/showLogon.do" > urlFlash1 = urlBase // "showFlashCheck.do" > urlFlash2 = urlBase // "logon.do?flashVersion=10.1.102" > urlShowWebForwards = urlBase // "showWebForwards.do" > urlGetResource = urlBase // "resourceList.do?form=webForwardsForm&readOnly=false&policyLaunching=true&resourcePrefix=webForwards&path=%2FshowWebForwards.do&messageResourcesKey=webForwards&actionPath=%2FresourceList.do" > urlCreateWebForward = urlBase // "quickCreateWebForward.do?actionTarget=create&actionPath=%2FquickCreateWebForward.do%3FactionTarget%3Dcreate&quickCreate=true&evalJS=true&evalScripts=true" > urlLogOut = urlBase // "logoff.do" > urlQuickCreate = urlBase // "quickCreateWebForward.do?actionTarget=create&actionPath=%2FquickCreateWebForward.do%3FactionTarget%3Dcreate&quickCreate=true&evalJS=true&evalScripts=true" > module HtmlParsing > ( > obtainCookies > ,generateResourceHtml > ) where > import Text.HTML.TagSoup > import Data.List.Split > import Data.List > import Data.Maybe > import Numeric > import Network.Curl > import Control.Monad > import Control.Monad.Error > import SessionCreator > processHTML :: String -> [[String]] > processHTML htmlFILE = > let parsedHTML = parseTags htmlFILE > allTagOpens = sections (~== TagOpen "a" [("href","")]) parsedHTML > taggedTEXT = head $ map (filter isTagOpen) allTagOpens > allHREFS = map (fromAttrib "href") taggedTEXT > allPotentials = map (dropWhile (/= '?')) allHREFS > removedNulls = filter (not . null) allPotentials > removedQs = map (drop 1) removedNulls > in map (splitOn "&") removedQs > createIDList :: [[String]] -> [String] > createIDList strungPairs = > let nvList = map (map (splitOn "=")) strungPairs > nvTuple = map (map (list2Tuple)) nvList > netofResources = map (lookup "resourceId") nvTuple > removedNothings = catMaybes netofResources > sortedIds = (map head . group . sort) $ map (\x -> read x :: Int) removedNothings > in map ("ResourceId" %%) $ map show sortedIds > list2Tuple :: [a] -> (a,a) > list2Tuple [x,y] = (x,y) > (%%) :: String -> String -> String > a %% b = a ++ "=" ++ b > generateResourceHtml :: Curl -> String -> String -> IO (Either String String) > generateResourceHtml curl user pass = do > let makeIDPage = do > curlResp curl urlInitial method_GET > curlResp curl urlLogin $ loginOpts user pass > curlResp curl urlFlash1 resourceOpts > curlResp curl urlFlash2 resourceOpts > curlResp curl urlShowWebForwards resourceOpts > curlResp curl urlQuickCreate resourceOpts > curlResp curl urlGetResource resourceOpts > runErrorT makeIDPage > obtainCookies :: Curl -> String -> IO () > obtainCookies curl responseBody = do > mapM_ (flip (curlResp curl) resourceOpts) $ > screenScraping responseBody > screenScraping :: String -> [String] > screenScraping responseBody = > let collectedStrings = processHTML responseBody > collectedIDLists = createIDList collectedStrings > in constructedResourceURIs urlBase collectedIDLists > constructedResourceURIs :: String -> [String] -> [String] > constructedResourceURIs url resourceIDs = > let frontURI = url ++ "/launchWebForward.do?" > midURI = map (frontURI ++) resourceIDs > in map (++ "&policy=0&returnTo=%2FshowWebForwards.do") midURI Here is the toy (produces a cookiejar) program. Attached are all the output files {-# LANGUAGE FlexibleContexts #-} module Main where ------------------------------------------------------------------------------ -- Imports ------------------------------------------------------------------------------ import Control.Monad import Control.Monad.Error import Network.Curl import System.Environment (getArgs) ------------------------------------------------------------------------------ -- Curl ------------------------------------------------------------------------------ initCurl :: IO Curl initCurl = do curl <- initialize setopts curl curlOpts return curl curlOpts :: [CurlOption] curlOpts = [ CurlCookieSession True , CurlCookieJar "cookies.txt" , CurlCookieFile "cookies.txt" , CurlFollowLocation True , CurlUserAgent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" , CurlVerbose True ] loginOpts :: String -> String -> [CurlOption] loginOpts user pass = [ CurlFailOnError True , CurlPost True , CurlNoBody False , CurlPostFields [ "_charset_=UTF-8" , "javaScript=true" , "username=" ++ user , "password=" ++ pass ] ] curlResp :: (MonadError String m, MonadIO m) => Curl -> URLString -> [CurlOption] -> m String --CurlResponse curlResp curl url opts = do resp <- liftIO $ (do_curl_ curl url opts :: IO CurlResponse) let code = respCurlCode resp status = respStatus resp if code /= CurlOK || status /= 200 then throwError $ "Error: " ++ show code ++ " -- " ++ show status else return $ respBody resp ------------------------------------------------------------------------------ -- URLs ------------------------------------------------------------------------------ (//) :: String -> String -> String a // b = a ++ "/" ++ b urlBase :: URLString urlBase = "https://172.16.1.18" urlInitial = urlBase // "showLogon.do" urlLogin = urlBase // "default/showLogon.do" urlFlash1 = urlBase // "showFlashCheck.do" urlFlash2 = urlBase // "logon.do?flashVersion=9.0.100" urlLaunch = urlBase // "launchWebForward.do?resourceId=4&policy=0&returnTo=%2FshowWebForwards.do" urlLaunchTest = urlBase // "launchWebForward.do?resourceId=5&policy=0&returnTo=%2FshowWebForwards.do" curlResp :: (MonadError String m, MonadIO m) => Curl -> URLString -> [CurlOption] -> m String --CurlResponse curlResp curl url opts = do resp <- liftIO $ (do_curl_ curl url opts :: IO CurlResponse) let code = respCurlCode resp status = respStatus resp if code /= CurlOK || status /= 200 then throwError $ "Error: " ++ show code ++ " -- " ++ show status else return $ respBody resp ------------------------------------------------------------------------------ -- URLs ------------------------------------------------------------------------------ (//) :: String -> String -> String a // b = a ++ "/" ++ b urlBase :: URLString urlBase = "https://172.16.1.18" urlInitial = urlBase // "showLogon.do" urlLogin = urlBase // "default/showLogon.do" urlFlash1 = urlBase // "showFlashCheck.do" urlFlash2 = urlBase // "logon.do?flashVersion=9.0.100" urlLaunch = urlBase // "launchWebForward.do?resourceId=4&policy=0&returnTo=%2FshowWebForwards.do" urlLaunchTest = urlBase // "launchWebForward.do?resourceId=5&policy=0&returnTo=%2FshowWebForwards.do" ------------------------------------------------------------------------------ -- IO ------------------------------------------------------------------------------ launch :: String -> String -> IO (Either String String) launch user pass = do -- Initialize Curl curl <- initCurl -- Sequence of steps let steps = do curlResp curl urlInitial method_GET curlResp curl urlLogin $ loginOpts user pass curlResp curl urlFlash1 method_GET curlResp curl urlFlash2 method_GET curlResp curl urlLaunch method_GET -- curlResp curl urlLaunchTest method_GET -- You'd use this to catch the exception right away -- `catchError` \e-> ... runErrorT steps main :: IO () main = do -- username and password user:pass:_ <- getArgs -- Launch webpage resp <- launch user pass -- Response comes as Either String String -- You have to handle each case case resp of Left err -> print err Right body -> putStrLn body So to sum up again, I'm trying to figure out why the toy program generates a cookie jar and the other program does everything it should *except* produce a cookie jar. Thanks to anyone who wants to slog through this. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://www.haskell.org/pipermail/beginners/attachments/20110131/5d5cd349/attachment.htm> -------------- next part -------------- A non-text attachment was scrubbed... Name: production_headers Type: application/octet-stream Size: 57684 bytes Desc: not available URL: <http://www.haskell.org/pipermail/beginners/attachments/20110131/5d5cd349/attachment.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: production_log Type: application/octet-stream Size: 1565292 bytes Desc: not available URL: <http://www.haskell.org/pipermail/beginners/attachments/20110131/5d5cd349/attachment-0001.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: toy_headers Type: application/octet-stream Size: 24335 bytes Desc: not available URL: <http://www.haskell.org/pipermail/beginners/attachments/20110131/5d5cd349/attachment-0002.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: toy_strace Type: application/octet-stream Size: 713169 bytes Desc: not available URL: <http://www.haskell.org/pipermail/beginners/attachments/20110131/5d5cd349/attachment-0003.obj> ------------------------------ _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners End of Beginners Digest, Vol 31, Issue 40 *****************************************