×
Samples Blogs Make Payment About Us Reviews 4.9/5 Order Now

Simple Query Language in Haskell, and Provide Routines for Dealing with CSV Files in Haskell Assignment Solution

June 19, 2024
Professor Marcus Johnson
Professor Marcus
🇦🇺 Australia
Haskell
Professor Marcus Johnson is an experienced Haskell programmer with a background in Mathematics and Computer Science. With over 600 completed assignments, Professor Johnson specializes in teaching functional programming concepts, category theory, and lambda calculus in Haskell. He is known for his clear explanations and passion for sharing his knowledge with students.
Key Topics
  • Instructions
    • Objective
  • Requirements and Specifications
Tip of the day
Familiarize yourself with OCaml's pattern matching; it simplifies handling recursive data structures like lists and trees, making your code concise and easier to debug.
News
In 2024, Girls Who Code introduced a Data Science + AI track in their free summer programs for high school students, fostering skills in cybersecurity and creative coding​

Instructions

Objective

Write a haskell assignment program, and provide routines for dealing with CSV files in haskell.

Requirements and Specifications

{------------------------------------------------------------------------}

{- Part 1 : CSV Files (25 marks) -}

{------------------------------------------------------------------------}

{- This part involves outputing, filtering, and parsing CSV (comma

separated values) files.

A CSV file represented in memory consists of a header with some

field names, and a list of records: -}

type CSVFile = (FieldNames, [CSVRecord]) {- where a record is a list of Strings: -} type CSVRecord = [String] {- and so are fieldnames: -} type FieldNames = [String] {- Here is an example 'database' of mountains in Scotland with their heights in metres: -} mountains :: CSVFile mountains = ( ["name", "height"], [ ["Ben Nevis", "1345"] , ["Ben Macdui", "1309"] , ["Braeriach", "1296"] , ["Cairn Toul", "1291"] , ["Sgor an Lochain Uaine", "1258"] , ["Cairn Gorm", "1245"] , ["Aonach Beag", "1234"] , ["Aonach Mòr", "1220"] , ["Càrn Mòr Dearg", "1220"] , ["Ben Lawers", "1214"] , ["Beinn a' Bhùird", "1197m"] , ["Beinn Mheadhoin", "very, very high"] ]) {- Of course, as with any real world database, this database contains nonsense and needs to be cleaned. Here is a fixed version: -} mountainsFixed :: CSVFile mountainsFixed = ( ["name", "height"], [ ["Ben Nevis", "1345"] , ["Ben Macdui", "1309"] , ["Braeriach", "1296"] , ["Cairn Toul", "1291"] , ["Sgor an Lochain Uaine", "1258"] , ["Cairn Gorm", "1245"] , ["Aonach Beag", "1234"] , ["Aonach Mòr", "1220"] , ["Càrn Mòr Dearg", "1220"] , ["Ben Lawers", "1214"] , ["Beinn a' Bhùird", "1197"] , ["Beinn Mheadhoin", "1183"] ]) {- 3.2.0 Printing CSV Files

Write a function that converts a 'CSVFile' to a String as an actual

comma separated file.

For the purposes of this exercise, the format of a CSV file is:

- A sequence of records, where each record is on a line terminated

with either a newline ('\n', Unix-style) or a CRLF ('\r\n',

Windows-style).

- Each record consists of zero or more fields separated by commas

(',')

- Each field is either:

- a sequence of non-comma and non-newline characters; or

- zero or more spaces (which are ignored), a quoted string, and

zero or more spaces (again ignored).

The first record is taken to be the fieldnames, and the remaining

records are normal data (so there must be at least one line).

Note that there are choices when outputing strings as CSV

fields. It is always safe to output them with quotes (as long as

you quote any special characters like '"'s or newlines), but you

will get more marks if you are selective about which fields you

quote. For example, we could quote everything:

Source Code

MAIN

module Main where import Data.List (intersperse) import System.Environment (getArgs) import System.Exit (exitFailure) import Control.Monad (filterM) import Result import ParserCombinators import Ex3 {- 3.3.0 Edit to this to implement a command line tool for filtering CSV files: -} liftResult :: Result a -> IO a liftResult (Ok a) = return a liftResult (Error msg) = do putStrLn ("ERROR: " ++ msg) exitFailure filterCSVFile :: Expr -> CSVFile -> Result CSVFile filterCSVFile expr (hdr, xs) = do fs <- (filterM filterBool xs) return (hdr, fs) where filterBool ys = do x <- (eval (zip hdr (map (\s -> StringValue s) ys)) expr); case x of BoolValue True -> return True BoolValue False -> return False _ -> Error "Expected boolean expression" processFile :: String -> String -> String -> IO() processFile exprs fname fields = do contents <- readFile fname csv <- liftResult $ parseWith parseCSVFile contents expr <- liftResult $ parseWith parseExpr exprs (h, s) <- liftResult $ filterCSVFile expr csv case fields of [] -> putStr (stringOfCSVFile (h, s)) fs -> do flds <- liftResult $ parseWith (sepBy (isChar ',') parseCSVField) fs; if and (map (\n -> (inArray n h)) flds) then putStr (stringOfCSVFile (filterField flds (h, s))) else do putStrLn "ERROR: Invalid filter field"; exitFailure where filterField field (h,s) = (filter (\n -> (inArray n field)) h,(map (\z -> map (\(_,c) -> c) (filter (\(n,_) -> (inArray n field)) z)) (map (\x-> zip h x) s))) inArray xs ys = any (\y -> xs == y) ys main :: IO () main = do args <- getArgs case args of [] -> do putStrLn ("Usage: Ex3 expr CSV \"field1,field2,...\""); exitFailure [_] -> do putStrLn ("ERROR: missing CSV filename"); exitFailure [exprs, fname] -> processFile exprs fname "" [exprs,fname,fs] -> processFile exprs fname fs _ -> do putStrLn ("ERROR: too many arguments"); exitFailure

Similar Samples

Visit ProgrammingHomeworkHelp.com to view our diverse array of programming homework samples. These examples highlight our proficiency in Java, Python, C++, and more, demonstrating our commitment to delivering high-quality solutions. Explore our samples to see how we can assist you in achieving academic success and mastering programming concepts