Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I should start by iterating what everyone would (and should) say: Start with a book like Real World Haskell! That said, I'll post a quick walkthrough of code that compiles, and hopefully does something close to what you originally intended. Comments are inline, and hopefully should illustrate some of the shortcomings of your approach.</p> <pre><code>import Text.Regex.Posix -- Let's start by wrapping your first attempt into a 'Monadic Action' -- IO is a monad, and hence we can sequence 'actions' (read as: functions) -- together using do-notation. attemptOne :: IO [[String]] -- ^ type declaration of the function 'attemptOne' -- read as: function returning value having type 'IO [[String]]' attemptOne = do putStrLn "type text file" filePath &lt;- getLine fileData &lt;- readFile filePath putStrLn fileData let parsed = fileData =~ "[^- \".,\n]+" :: [[String]] -- ^ this form of let syntax allows us to declare that -- 'wherever there is a use of the left-hand-side, we can -- substitute it for the right-hand-side and get equivalent -- results. putStrLn ("The data after running the regex: " ++ concatMap concat parsed) return parsed -- ^ return is a monadic action that 'lifts' a value -- into the encapsulating monad (in this case, the 'IO' Monad). -- Here we show that given a search term (a String), and a body of text to -- search in, we can return the frequency of occurrence of the term within the -- text. searchingFunc :: String -&gt; [String] -&gt; Int searchingFunc term = length . filter predicate where predicate = (==)term -- ^ we use function composition (.) to create a new function from two -- existing ones: -- filter (drop any elements of a list that don't satisfy -- our predicate) -- length: return the size of the list -- Here we build a wrapper-function that allows us to run our 'pure' -- searchingFunc on an input of the form returned by 'attemptOne'. runSearchingFunc :: String -&gt; [[String]] -&gt; [Int] runSearchingFunc term parsedData = map (searchingFunc term) parsedData -- Here's an example of piecing everything together with IO actions main :: IO () main = do results &lt;- attemptOne -- ^ run our attemptOne function (representing IO actions) -- and save the result let searchResults = runSearchingFunc "foo" results -- ^ us a 'let' binding to state that searchResults is -- equivalent to running 'runSearchingFunc' print searchResults -- ^ run the IO action that prints searchResults print (runSearchingFunc "foo" results) -- ^ run the IO action that prints the 'definition' -- of 'searchResults'; i.e. the above two IO actions -- are equivalent. return () -- as before, lift a value into the encapsulating Monad; -- this time, we're lifting a value corresponding to 'null/void'. </code></pre> <p>To load this code, save it into a .hs file (I saved it into 'temp.hs'), and run the following from ghci. Note: the file 'f' contains a few input words:</p> <pre><code>*Main Text.Regex.Posix&gt; :l temp.hs [1 of 1] Compiling Main ( temp.hs, interpreted ) Ok, modules loaded: Main. *Main Text.Regex.Posix&gt; main type text file f foo foos foor fo foo foo The data after running the regex: foofoosfoorfofoofoo [1,0,0,0,1,1] [1,0,0,0,1,1] </code></pre> <p>There is a lot going on here, from do notation to Monadic actions, 'let' bindings to the distinction between pure and impure functions/values. I can't stress the value of learning the fundamentals from a good book! </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload