cookbook 2.3.4.5 → 3.0.1.1
raw patch · 26 files changed
Files
- Cookbook/Essential/Common.hs +3/−3
- Cookbook/Essential/Continuous.hs +8/−4
- Cookbook/Essential/IO.hs +1/−3
- Cookbook/Ingredients/Lists/Access.hs +1/−2
- Cookbook/Ingredients/Lists/Encompass.hs +1/−26
- Cookbook/Ingredients/Lists/Modify.hs +3/−6
- Cookbook/Ingredients/Lists/Stats.hs +0/−14
- Cookbook/Ingredients/Tupples/Look.hs +2/−2
- Cookbook/Meta.hs +2/−2
- Cookbook/Project/Quill/Quill.hs +0/−85
- Cookbook/Project/Quill/Quill2/Meta.hs +0/−9
- Cookbook/Project/Quill/Quill2/Q2Api.hs +0/−105
- Cookbook/Project/Quill/Quill2/Q2Io.hs +0/−31
- Cookbook/Project/Quill/Quill2/Q2Parse.hs +0/−45
- Cookbook/Project/Quill/Quill2/Q2Prelude.hs +0/−23
- Cookbook/Project/Quill2/Meta.hs +9/−0
- Cookbook/Project/Quill2/Q2Api.hs +102/−0
- Cookbook/Project/Quill2/Q2Io.hs +30/−0
- Cookbook/Project/Quill2/Q2Parse.hs +44/−0
- Cookbook/Project/Quill2/Q2Prelude.hs +23/−0
- Cookbook/Recipes/Algorithm.hs +5/−6
- Cookbook/Recipes/Cline.hs +7/−3
- Cookbook/Recipes/Math.hs +0/−0
- Cookbook/Recipes/Meta.hs +1/−3
- Cookbook/Recipes/Sanitize.hs +0/−0
- cookbook.cabal +40/−5
Cookbook/Essential/Common.hs view
@@ -1,6 +1,6 @@ {- | Module : Cookbook.Essential.Common- Copyright : (c) 2014 by Nate Pisarski+ Copyright : (c) 2015 by Nate Pisarski License : BSD3 Maintainer : nathanpisarski@gmail.com Stability : Stable@@ -15,8 +15,8 @@ sub :: (Eq a) => [a] -> Int -> [a] sub [] _ = [] sub x 0 = x-sub (x:xs) c = sub xs (c - 1)-+sub (_:xs) c = sub xs (c - 1)+ -- | Find the occurrences of an element in a list. positions :: (Eq a) => [a] -> a -> [Int] positions x c = let y = zip x [0..(length x)] in find y
Cookbook/Essential/Continuous.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE FlexibleInstances #-}- {-# LANGUAGE MultiParamTypeClasses #-} {- |@@ -27,7 +26,7 @@ -- | Returns all elements after part. before :: list -> part -> list-+ -- | Removes part from the list. delete :: list -> part -> list @@ -48,16 +47,21 @@ -- | Classifies information which can be split by a tupple. class Splicable a b where-+ -- | Removes everything between the tupple's parameters, including the parameters themselves. splice :: a -> b -> a-+ between :: a -> b -> a+ instance (Eq a) => Splicable [a] (a,a) where splice ls (a,b) = before ls a ++ Cm.fromLast (`before` b) ls + between a (b,c) = before (after a b) c+ instance (Eq a) => Splicable [a] ([a],[a]) where splice ls (a,b) = before ls a ++ after (after ls a) b + between a (b,c) = before (after a b) c+ -- | Classifies data which can be replaced. class Replacable list repls where
Cookbook/Essential/IO.hs view
@@ -15,9 +15,7 @@ import qualified System.IO.Strict as SIO import qualified Cookbook.Essential.Common as Cm import qualified Cookbook.Essential.Continuous as Ct-import qualified Cookbook.Ingredients.Lists.Modify as Md--import System.Environment + import System.Directory -- | Return the lines of a file as a list of Strings.
Cookbook/Ingredients/Lists/Access.hs view
@@ -10,8 +10,7 @@ module Cookbook.Ingredients.Lists.Access where import qualified Cookbook.Ingredients.Functional.Break as Br-import qualified Cookbook.Ingredients.Tupples.Assemble as As-import qualified Cookbook.Essential.Common as Cm+import qualified Cookbook.Essential.Common as Cm -- | Counts the occurrences an element has within a list. count :: (Eq a) => [a] -> a -> Int
Cookbook/Ingredients/Lists/Encompass.hs view
@@ -21,7 +21,7 @@ helper [] _ = [] helper (y:ys) e | y == b && e <= 1 = []- | y == a && a == b = if e == 0 then [] else condInp $ helper ys (e + 1)+ | y == a && a == b = if e == 0 then [] else condInp $ helper ys ((e :: Integer )+ 1) | y == a = condInp $ helper ys (e + 1) | y == b = y : helper ys (e - 1) | otherwise = condInp $ helper ys e@@ -44,21 +44,6 @@ | not $ f `elem` e && g `elem` e = [e] | otherwise = beforeEncompassing e (f,g) : splitEncompassing (afterEncompassing e (f,g)) (f,g) --- | There is a long story behind this function, and why it sucks. See ENN1 in the source.-notEncompassedSplit :: (Eq a) => [a] -> (a,a) -> a -> [[a]]-notEncompassedSplit [] _ _ = [] -- "b{c,d},e,{f:g,e:h}"-notEncompassedSplit ls (sp1,sp2) sp = toGaps $ helper ls 0- where- helper [] _ = []- helper (x:xs) c- | x == sp1 && c >= 0 = (sp1: encompassing (x:xs) (sp1,sp2)) : helper (afterEncompassing xs (sp1,sp2)) (c + 1)- | x == sp2 && c <= 0 = [x] : helper xs (c - 1)- | x == sp1 = [x] : helper xs (c+1)- | x == sp2 = [x] : helper xs (c - 1)- | x == sp && c > 0 = [x] : helper xs c- | x == sp && c <= 0 = [] : helper xs c- | otherwise = [x] : helper xs c- toGaps :: (Eq a) => [[a]] -> [[a]] toGaps [] = [] toGaps x@@ -70,13 +55,3 @@ gatherEncompassing a (b,c) | not $ b `elem` a && c `elem` a = [] | otherwise = encompassing a (b,c) : gatherEncompassing (afterEncompassing a (b,c)) (b,c)---- [ENN1]--- This function is terrible. Bloody AWFUL. So, why include it? Because it works.--- the implementation of the function is hard to rework, so unfortunately it doesn't--- get much better than this. I've tried rereading it time and time again, and the--- details of how it works confuse me. Prior to making the function, I spent--- more than a month thinking about how it should work. After that didn't work--- I began to change variables and behaviors in a fit of rage, and it started--- to work. And don't question the helper function either. This is as good--- as it gets, ladies and gentlemen.
Cookbook/Ingredients/Lists/Modify.hs view
@@ -9,7 +9,6 @@ -} module Cookbook.Ingredients.Lists.Modify where -import qualified Cookbook.Essential.Common as Cm import qualified Cookbook.Essential.Continuous as Ct import qualified Cookbook.Ingredients.Functional.Break as Br import qualified Cookbook.Ingredients.Lists.Access as Ac@@ -28,10 +27,6 @@ splitOn [] _ = [] splitOn x c = if c `notElem` x then [x] else Ct.before x c : splitOn (Ct.after x c) c --- | Returns the data between two items.-between :: (Eq a) => [a] -> (a,a) -> [a]-between a (c,d) = Ct.after (take (last $ Cm.positions a d) a) c- -- | Implementation of between that works on a list of lists, and using Contains rather than elem. linesBetween :: (Eq a) => [[a]] -> ([a],[a]) -> [[a]] linesBetween a (c,d) = tail $ Br.filterBreak (\e -> not $ Ac.contains e d) $ Br.removeBreak (\e -> not $ Ac.contains e c) a@@ -52,7 +47,9 @@ -- [MDN1] -- This is implemented in Continuous, but is kept here for historical purposes,--- or for when Continuous is too heavy-duty for whatever job you are on.+-- or for when Continuous is too heavy-duty for whatever job you are on. Also,+-- Continuous makes use of non-portable pragmas, and the rm implementation here+-- is just pure haskell. -- [MDN2] -- encompassingScope has been renamed to "encompassing" and moved to its own module with similar functions, Cookbook.Ingredients.Lists.Encompass
Cookbook/Ingredients/Lists/Stats.hs view
@@ -13,8 +13,6 @@ import qualified Cookbook.Ingredients.Lists.Access as Ac import qualified Cookbook.Ingredients.Lists.Modify as Md import qualified Cookbook.Ingredients.Tupples.Assemble as As-import qualified Cookbook.Recipes.Sanitize as Sn-import qualified Cookbook.Recipes.Math as Ma -- | Creates a list with the frequency of elements in a list. frequency :: (Eq a) => [a] -> [(a,Int)] @@ -23,15 +21,3 @@ -- | Returns the x-amount of most frequent elements in a list. If there is a "tie", the order it appears in a list takes precedence. mostFrequent :: (Eq a) => [a] -> Int -> [a] mostFrequent x c = take c $ Md.rev (As.assemble $ frequency x)---- | Provides a mathematical score out of 1 based on the similarities between the two words. This is freqScore, but it takes into account length.-wordscore :: (Eq a) => [a] -> [a] -> Double-wordscore a b = (freqScore a b - 0.1) + (0.1 / realToFrac (if diffLen == 0 then 1 else diffLen))- where diffLen = abs $ length a - length b---- | Provides a frequency score between two lists.-freqScore :: (Eq a) => [a] -> [a] -> Double-freqScore a b = rawFreq / fromIntegral diffLen- where diffLen = fromIntegral $ length (frequency (if length (frequency a) < length (frequency b) then a else b))- rawFreq = fromIntegral (sum $ map (\e -> if e `elem` d then 1 else 0) c)- (c:d:_) = map (`mostFrequent` diffLen) [a,b]
Cookbook/Ingredients/Tupples/Look.hs view
@@ -18,7 +18,7 @@ -- | Returns all elements where the lval matches the element. lookList :: (Eq a) => [(a,b)] -> a -> [b]-lookList a b = map snd $ filter (\(c,d) -> c == b) a+lookList a b = map snd $ filter (\(c,_) -> c == b) a -- | Swap the lval with the rval, and vice-versa. swp :: (a,b) -> (b,a)@@ -32,5 +32,5 @@ -- | Turns a list into as many double-tupples (a,a) as it can, dropping items from uneven lists. group :: [a] -> [(a,a)] group [] = []-group [x] = []+group [_] = [] group (x:y:z) = (x,y) : group z
Cookbook/Meta.hs view
@@ -1,7 +1,7 @@ module Cookbook.Meta(module Cookbook.Ingredients.Meta, module Cookbook.Recipes.Meta,- module Cookbook.Project.Quill.Quill2.Meta) where+ module Cookbook.Project.Quill2.Meta) where import Cookbook.Ingredients.Meta import Cookbook.Recipes.Meta-import Cookbook.Project.Quill.Quill2.Meta+import Cookbook.Project.Quill2.Meta
− Cookbook/Project/Quill/Quill.hs
@@ -1,85 +0,0 @@-{- |- Module : Cookbook.Project.Quill.Quil- Copyright : (c) 2014 by Nate Pisarski- License : BSD3- Maintainer : nathanpisarski@gmail.com- Stability : Stable- Portability : Portable (Cookbook-A library for reading simple databases. As what was originally a quirk of the library, database tables can be split up and still parsed as if they were a unit, giving it the ability to read the same table from multiple files in parallel. Quill supports a comment syntax, whitespace-insignificant parsing, and a full CRUD API. Quill will EVENTUALLY be replaced by Scribe2, but the planning for Scribe2 has not yet begun.--}-module Cookbook.Project.Quill.Quill {-# DEPRECATED "Quill2 Deprecates this. Scheduled for removal on June 1st, 2014." #-} where --import qualified Cookbook.Essential.Common as Cm-import qualified Cookbook.Essential.Continuous as Ct-import qualified Cookbook.Ingredients.Lists.Modify as Md-import qualified Cookbook.Ingredients.Lists.Access as Ac-import qualified Cookbook.Ingredients.Tupples.Look as Lk-import qualified Cookbook.Recipes.Sanitize as Sn---- | A table is a record of a name and the information within it.-data Table = Table {name :: String, info :: [(String,String)]}---- | Sanitizes strings for Quill processing. Removes comments, newlines, and flattens it into a string.-prepare :: [String] -> String-prepare = (`Ct.splice` ("(*","*)")) . (`Sn.blacklist` "\n") . Cm.flt---- | Splits a list into tupples.-tokenize :: [a] -> [(a,a)]-tokenize [] = []-tokenize [x] = []-tokenize (x:y:xs) = (x,y) : tokenize xs---- | Returns the names of all tables in the file.-tblNames :: String -> [String]-tblNames x = Ct.before x '{' : tail (Md.surroundedBy (Sn.blacklist x " ") ('}','{'))---- | *Should not be used raw except for API programming. Really shouldn't be included, but too lazy to enumerate top-level declarations for selective export* Returns all entry lines from within tables in database.-headlessData :: String -> [[String]]-headlessData x = map (`Md.splitOn` ';') $ Md.surroundedBy x ('{','}')---- | Returns all of the tokens from headlessData.-tokenLists :: [[String]] -> [[(String,String)]]-tokenLists = map (map (\c -> (Ct.before c ':',Ct.after c ':')))---- API functions--- | Creates a listing of all tables in the file.-tables :: [String] -> [(String,[(String,String)])]-tables x = let y = prepare x in- zip (tblNames y) $ tokenLists (headlessData y)---- | Gets a particular table in the file, returning its key-value pairs.-getTable :: [(String,[(String,String)])] -> String -> [(String,String)]-getTable x c = Cm.flt $ Lk.lookList x c---- | Gets the particular item within a table from a database.-lookUp :: [(String,[(String,String)])] -> (String,String) -> [String]-lookUp x (c,d) = (`Lk.lookList` d) $ getTable x c---- | Creates a new table within the database.-createTable :: [(String,[(String,String)])] -> String -> [(String,[(String,String)])]-createTable x c = (c,[]) : x---- | Removes an entire table from the database by name.-removeTable :: [(String,[(String,String)])] -> String -> [(String,[(String,String)])]-removeTable x c = [e | e@(d,_) <- x, d /= c] -- WOAH what does this do?---- | Removes a particular item from a table within a database.-removeItem :: [(String,[(String,String)])] -> (String,String) -> [(String,[(String,String)])]-removeItem [] _ = []-removeItem ((tbl,ite):re) (tb,it)- | tbl == tb = (tbl,filter (\(c,d) -> c /= it) ite) : removeItem re (tb,it)- | otherwise = (tbl,ite) : removeItem re (tb,it)---- | Adds an item to a table within a database.-addItem :: [(String,[(String,String)])] -> String -> (String,String) -> [(String,[(String,String)])]-addItem [] _ _ = []-addItem ((a,b):c) tb it = if a == tb then (a,it:b) : addItem c tb it else (a,b) : addItem c tb it---- | Changes an item within a table. The identifier will remain the same; only the rvalue will change.-changeItem :: [(String,[(String,String)])] -> (String,String) -> String -> [(String,[(String,String)])]-changeItem db (tb,it) c = addItem (removeItem db (tb,it)) tb (it,c)---- | Basically a toString function for Quill tables. It turns data into a String format which can be parsed by the Quill parsing stack.-tableToString :: (String,[(String,String)]) -> String-tableToString (x,b) = x ++ "{" ++ Cm.flt (map detokenize b) ++ "}"- where detokenize (a,b) = a ++ ":" ++ b ++ ";"
− Cookbook/Project/Quill/Quill2/Meta.hs
@@ -1,9 +0,0 @@-module Cookbook.Project.Quill.Quill2.Meta(module Cookbook.Project.Quill.Quill2.Q2Api,- module Cookbook.Project.Quill.Quill2.Q2Io,- module Cookbook.Project.Quill.Quill2.Q2Parse,- module Cookbook.Project.Quill.Quill2.Q2Prelude) where--import Cookbook.Project.Quill.Quill2.Q2Api-import Cookbook.Project.Quill.Quill2.Q2Io-import Cookbook.Project.Quill.Quill2.Q2Parse-import Cookbook.Project.Quill.Quill2.Q2Prelude
− Cookbook/Project/Quill/Quill2/Q2Api.hs
@@ -1,105 +0,0 @@-{- |- Module : Cookbook.Project.Quill.Quill2.Q2Api- Copyright : (c) 2014 by Nate Pisarski- License : BSD3- Maintainer : nathanpisarski@gmail.com- Stability : Stable- Portability : Portable (Cookbook)-Q2Api is the user-facing part of Quill. It has all the functions necessar to Create, Read, Update, and Delete information from the database, and turn a database back into a Quill-readable string.--}--module Cookbook.Project.Quill.Quill2.Q2Api where--import qualified Cookbook.Ingredients.Tupples.Look as Lk-import qualified Cookbook.Essential.Common as Cm-import qualified Cookbook.Essential.Continuous as Ct-import qualified Cookbook.Ingredients.Lists.Access as Ac--import Cookbook.Project.Quill.Quill2.Q2Prelude-import Cookbook.Project.Quill.Quill2.Q2Parse---- | Get the name of a Quill.-getQuillName :: Quill -> String-getQuillName = fst---- | Return the element of the Quill, specifically useful for lists.-getQuillBody :: Quill -> Element String-getQuillBody = snd---- | Find a quill in the database by name, returning it or a possible error type.-getQuill :: [Quill] -> String -> QuillStatus Quill-getQuill [] c = QuillMissing c-getQuill (x:xs) c- | Ac.count (map getQuillName (x:xs)) c > 1 = QuillMultiple c- | getQuillName x == c = QuillSuccess x- | otherwise = getQuill xs c---- | Look up the value of a Quill TABLE. Will produce an error on a list.-lookUp :: [Quill] -> (String, String) -> QuillStatus String-lookUp x (a,b) = case getQuill x a of- (QuillSuccess (c,d)) -> case d of- (List f) -> error "Cannot look up the value of a list."- (Table f) -> let c = Lk.lookList f b in if null c|| (length c > 1) then QuillMissing b else QuillSuccess $ head c-- (QuillMissing _) -> QuillMissing a- (QuillMultiple _) -> QuillMultiple a- where multipleInnerError = QuillMultiple b---- | Remove a quill from the database by name.-removeQuill :: [Quill] -> String -> [Quill]-removeQuill [] _ = []-removeQuill ((x,y):xs) c- | x == c = removeQuill xs c -- See [Q2N1]- | otherwise = (x,y) : removeQuill xs c---- | Remove an item from a Quill within a database. Works aggressively, meaning it removes all copies to help sanitize QuillMultiples out. th-removeItem :: [Quill] -> (String, String) -> QuillStatus [Quill]-removeItem x (a,b) = case getQuill x a of- QuillSuccess (c,j) -> case j of- (Table d) -> QuillSuccess $ (c, Table [(y,t) | (y,t) <- d, y /= b]) : removeQuill x a- (List d) -> QuillSuccess $ (c,List $ Ct.remove d c) : removeQuill x a- QuillMissing _ -> QuillMissing a- QuillMultiple _ -> QuillMultiple a---- | Adds a Quill databse to the file.-addQuill :: [Quill] -> Quill -> [Quill]-addQuill x c = c : x---- | Add a QuillAddition to the databse. QuillAddition is a safe encapsulation of list and table values.-addItem :: [Quill] -> QuillAddition -> QuillStatus [Quill]-addItem x qa = case getQuill x a of- QuillSuccess (y, ys) -> case ys of- (Table d) -> case qa of- (ATable (_,b,c)) -> QuillSuccess $ (y,Table $ (b,c) : d) : removeQuill x a- (AList _ ) -> error $ "$ Type Mismatch! Attempted to add a List type to Table in table " ++ show qa- (List d) -> case qa of- (AList (_,b)) -> QuillSuccess $ (y, List (b:d)) : removeQuill x a- (ATable _) -> error $ "Type Mismatch! Attempted to add Table type to List in table " ++ show qa- QuillMultiple v -> QuillMultiple a- QuillMissing v -> QuillMissing a --M- where- a = case qa of- (ATable (g,b,c)) -> g- (AList (g,b)) -> g---- | Map a Quill function.-qMap :: QuillStatus [Quill] -> ([Quill] -> QuillStatus [Quill]) -> QuillStatus [Quill]-qMap c f = case c of- (QuillSuccess a) -> f a- _ -> c---- | Change an item within the database using a Quill addition. Wrapper of addItem and removeItem.-changeItem :: [Quill] -> QuillAddition -> QuillStatus [Quill]-changeItem x y = case y of- (ATable (a,b,c)) -> qMap (removeItem x (a,b)) (`addItem` y)- (AList (a,b)) -> qMap (removeItem x (a,b)) (`addItem` y)- ---- | Turn a Quill table into a string.-toString :: Quill -> String-toString (nm,typ) = case typ of- (List a) -> Cm.flt ["list(", nm, "){", Cm.flt (map (++ ";") a),"}"]- (Table a) -> Cm.flt ["table(", nm, "){", Cm.flt (stringify a), "}"]- where- stringify [] = []- stringify ((a,b):xs) = Cm.flt [a,":",b,";"] : stringify xs
− Cookbook/Project/Quill/Quill2/Q2Io.hs
@@ -1,31 +0,0 @@-{- |- Module : Cookbook.Project.Quill.Quill2.Q2Io- Copyright : (c) 2014 by Nate Pisarski- License : BSD3- Maintainer : nathanpisarski@gmail.com- Stability : Stable- Portability : Portable (Cookbook)-Q2Io is a helper library for interacting with Quill files. It aids in the reading of and writing to files on the user's system.--}--module Cookbook.Project.Quill.Quill2.Q2Io where--import qualified Cookbook.Project.Quill.Quill2.Q2Api as Q2Api--import qualified Cookbook.Essential.IO as Io--import Cookbook.Project.Quill.Quill2.Q2Prelude-import Cookbook.Project.Quill.Quill2.Q2Parse--import System.IO---- | Read a Quill database from a file.-fromFile :: FilePath -> IO [Quill]-fromFile x = do- y <- Io.filelines x- return $ pFile y---- | Send a Quill database into a parsable format in a file.-toFile :: FilePath -> [Quill] -> IO ()-toFile x f = writeFile x (unlines (map Q2Api.toString f))-
− Cookbook/Project/Quill/Quill2/Q2Parse.hs
@@ -1,45 +0,0 @@-{- |- Module : Cookbook.Project.Quill.Quill2.Q2Parse- Copyright : (c) 2014 by Nate Pisarski- License : BSD3- Maintainer : nathanpisarski@gmail.com- Stability : Stable- Portability : Portable (Cookbook)-Q2Parse is the "engine" of Quill2. It is able to turn a string (or a list of them) into a Quill database. The syntax of Quill currently supports Whitespace-inclusive strings, comments, and whitespace-independence.--}--module Cookbook.Project.Quill.Quill2.Q2Parse where--import qualified Cookbook.Essential.Common as Cm-import qualified Cookbook.Essential.Continuous as Ct--import qualified Cookbook.Ingredients.Lists.Modify as Md-import qualified Cookbook.Ingredients.Lists.Access as Ac-import qualified Cookbook.Ingredients.Lists.Encompass as En--import Cookbook.Project.Quill.Quill2.Q2Prelude---- | Remove all C-style comments frm the code. Does not support single-line comments, because Quill2 is fully whitespace independant.-decomment :: String -> String-decomment = (`Ct.splice` ("/*", "*/"))---- | Prepare the lines of a file for processing.-prepare :: [String] -> String-prepare = decomment . (`Ct.remove` '\n') . unlines---- | Process a single entry in the database into a Table.-pTable :: String -> Quill-pTable x = typ- where- name = Md.between (Ct.before x '{') ('(',')') --table(name) or list(name) gets name.- typ = (name,if Ct.before x '{' `Ac.contains` "table" then Table (parseTables body) else List body) -- Determines what kind of type the Quill is.- body = Md.splitOn (En.encompassing x ('{','}')) ';' - quoted y = if ('`','\'') `Ac.surrounds` y then En.encompassing x ('`','\'') else Ct.remove y ' ' -- Whole String encapsulation- parseTables = map (\x -> (quoted $ Ct.before x ':', Ct.after x ':'))---- | Turn the lines of a file into a list of tables, AKA a Database.-pFile :: [String] -> [Quill]-pFile x = map pTable $ Md.splitOn (prepare x) '}'---
− Cookbook/Project/Quill/Quill2/Q2Prelude.hs
@@ -1,23 +0,0 @@-{- |- Module : Cookbook.Project.Quill.Quill2.Q2Prelude- Copyright : (c) 2014 by Nate Pisarski- License : BSD3- Maintainer : nathanpisarski@gmail.com- Stability : Stable- Portability : Portable (Cookbook)-Q2Prelude is the entry-level module for Quill2. It defines the data types that define data, databases, and errors throughout the rest of Quill2.--}--module Cookbook.Project.Quill.Quill2.Q2Prelude where- --- | The body of a table or list.-data Element a = List [a] | Table [(a,a)] deriving (Eq, Show)---- | Helper type. Binds a name to a body.-type Quill = (String,Element String)---- | Encapsulates errors in the quill database. Currently supports Missing elements and Multiple Instances.-data QuillStatus a = QuillSuccess a | QuillMissing String | QuillMultiple String deriving (Eq, Show)--Find and change these.---- | Safe way of adding items to a Quill database. Allows type-checking on Lists and Tables when manipulating Elements.-data QuillAddition = AList (String, String) | ATable (String, String, String) deriving (Eq, Show)
+ Cookbook/Project/Quill2/Meta.hs view
@@ -0,0 +1,9 @@+module Cookbook.Project.Quill2.Meta(module Cookbook.Project.Quill2.Q2Api,+ module Cookbook.Project.Quill2.Q2Io,+ module Cookbook.Project.Quill2.Q2Parse,+ module Cookbook.Project.Quill2.Q2Prelude) where++import Cookbook.Project.Quill2.Q2Api+import Cookbook.Project.Quill2.Q2Io+import Cookbook.Project.Quill2.Q2Parse+import Cookbook.Project.Quill2.Q2Prelude
+ Cookbook/Project/Quill2/Q2Api.hs view
@@ -0,0 +1,102 @@+{- |+ Module : Cookbook.Project.Quill2.Q2Api+ Copyright : (c) 2014 by Nate Pisarski+ License : BSD3+ Maintainer : nathanpisarski@gmail.com+ Stability : Stable+ Portability : Portable (Cookbook)+Q2Api is the user-facing part of Quill. It has all the functions necessar to Create, Read, Update, and Delete information from the database, and turn a database back into a Quill-readable string.+-}++module Cookbook.Project.Quill2.Q2Api where++import qualified Cookbook.Ingredients.Tupples.Look as Lk+import qualified Cookbook.Essential.Common as Cm+import qualified Cookbook.Essential.Continuous as Ct+import qualified Cookbook.Ingredients.Lists.Access as Ac++import Cookbook.Project.Quill2.Q2Prelude++-- | Get the name of a Quill.+getQuillName :: Quill -> String+getQuillName = fst++-- | Return the element of the Quill, specifically useful for lists.+getQuillBody :: Quill -> Element String+getQuillBody = snd++-- | Find a quill in the database by name, returning it or a possible error type.+getQuill :: [Quill] -> String -> QuillStatus Quill+getQuill [] c = QuillMissing c+getQuill (x:xs) c+ | Ac.count (map getQuillName (x:xs)) c > 1 = QuillMultiple c+ | getQuillName x == c = QuillSuccess x+ | otherwise = getQuill xs c++-- | Look up the value of a Quill TABLE. Will produce an error on a list.+lookUp :: [Quill] -> (String, String) -> QuillStatus String+lookUp x (a,b) = case getQuill x a of+ (QuillSuccess (_,d)) -> case d of+ (List _) -> error "Cannot look up the value of a list."+ (Table f) -> let c = Lk.lookList f b in if null c|| (length c > 1) then QuillMissing b else QuillSuccess $ head c+ (QuillMissing _) -> QuillMissing a+ (QuillMultiple _) -> QuillMultiple a++-- | Remove a quill from the database by name.+removeQuill :: [Quill] -> String -> [Quill]+removeQuill [] _ = []+removeQuill ((x,y):xs) c+ | x == c = removeQuill xs c -- See [Q2N1]+ | otherwise = (x,y) : removeQuill xs c++-- | Remove an item from a Quill within a database. Works aggressively, meaning it removes all copies to help sanitize QuillMultiples out. th+removeItem :: [Quill] -> (String, String) -> QuillStatus [Quill]+removeItem x (a,b) = case getQuill x a of+ QuillSuccess (c,j) -> case j of+ (Table d) -> QuillSuccess $ (c, Table [(y,t) | (y,t) <- d, y /= b]) : removeQuill x a+ (List d) -> QuillSuccess $ (c,List $ Ct.remove d c) : removeQuill x a+ QuillMissing _ -> QuillMissing a+ QuillMultiple _ -> QuillMultiple a++-- | Adds a Quill databse to the file.+addQuill :: [Quill] -> Quill -> [Quill]+addQuill x c = c : x++-- | Add a QuillAddition to the databse. QuillAddition is a safe encapsulation of list and table values.+addItem :: [Quill] -> QuillAddition -> QuillStatus [Quill]+addItem x qa = case getQuill x a of+ QuillSuccess (y, ys) -> case ys of+ (Table d) -> case qa of+ (ATable (_,b,c)) -> QuillSuccess $ (y,Table $ (b,c) : d) : removeQuill x a+ (AList _ ) -> error $ "$ Type Mismatch! Attempted to add a List type to Table in table " ++ show qa+ (List d) -> case qa of+ (AList (_,b)) -> QuillSuccess $ (y, List (b:d)) : removeQuill x a+ (ATable _) -> error $ "Type Mismatch! Attempted to add Table type to List in table " ++ show qa+ QuillMultiple _ -> QuillMultiple a+ QuillMissing _ -> QuillMissing a --M+ where+ a = case qa of+ (ATable (g,_,_)) -> g+ (AList (g,_)) -> g++-- | Map a Quill function.+qMap :: QuillStatus [Quill] -> ([Quill] -> QuillStatus [Quill]) -> QuillStatus [Quill]+qMap c f = case c of+ (QuillSuccess a) -> f a+ _ -> c++-- | Change an item within the database using a Quill addition. Wrapper of addItem and removeItem.+changeItem :: [Quill] -> QuillAddition -> QuillStatus [Quill]+changeItem x y = case y of+ (ATable (a,b,_)) -> qMap (removeItem x (a,b)) (`addItem` y)+ (AList (a,b)) -> qMap (removeItem x (a,b)) (`addItem` y)+ ++-- | Turn a Quill table into a string.+toString :: Quill -> String+toString (nm,typ) = case typ of+ (List a) -> Cm.flt ["list(", nm, "){", Cm.flt (map (++ ";") a),"}"]+ (Table a) -> Cm.flt ["table(", nm, "){", Cm.flt (stringify a), "}"]+ where+ stringify [] = []+ stringify ((a,b):xs) = Cm.flt [a,":",b,";"] : stringify xs
+ Cookbook/Project/Quill2/Q2Io.hs view
@@ -0,0 +1,30 @@+{- |+ Module : Cookbook.Project.Quill2.Q2Io+ Copyright : (c) 2014 by Nate Pisarski+ License : BSD3+ Maintainer : nathanpisarski@gmail.com+ Stability : Stable+ Portability : Portable (Cookbook)+Q2Io is a helper library for interacting with Quill files. It aids in the reading of and writing to files on the user's system.+-}++module Cookbook.Project.Quill2.Q2Io where++import qualified Cookbook.Project.Quill2.Q2Api as Q2Api++import qualified Cookbook.Essential.IO as Io++import Cookbook.Project.Quill2.Q2Prelude+import Cookbook.Project.Quill2.Q2Parse+++-- | Read a Quill database from a file.+fromFile :: FilePath -> IO [Quill]+fromFile x = do+ y <- Io.filelines x+ return $ pFile y++-- | Send a Quill database into a parsable format in a file.+toFile :: FilePath -> [Quill] -> IO ()+toFile x f = writeFile x (unlines (map Q2Api.toString f))+
+ Cookbook/Project/Quill2/Q2Parse.hs view
@@ -0,0 +1,44 @@+{- |+ Module : Cookbook.Project.Quill2.Q2Parse+ Copyright : (c) 2014 by Nate Pisarski+ License : BSD3+ Maintainer : nathanpisarski@gmail.com+ Stability : Stable+ Portability : Portable (Cookbook)+Q2Parse is the "engine" of Quill2. It is able to turn a string (or a list of them) into a Quill database. The syntax of Quill currently supports Whitespace-inclusive strings, comments, and whitespace-independence.+-}++module Cookbook.Project.Quill2.Q2Parse where++import qualified Cookbook.Essential.Continuous as Ct++import qualified Cookbook.Ingredients.Lists.Modify as Md+import qualified Cookbook.Ingredients.Lists.Access as Ac+import qualified Cookbook.Ingredients.Lists.Encompass as En++import Cookbook.Project.Quill2.Q2Prelude++-- | Remove all C-style comments frm the code. Does not support single-line comments, because Quill2 is fully whitespace independant.+decomment :: String -> String+decomment = (`Ct.splice` ("/*", "*/"))++-- | Prepare the lines of a file for processing.+prepare :: [String] -> String+prepare = decomment . (`Ct.remove` '\n') . unlines++-- | Process a single entry in the database into a Table.+pTable :: String -> Quill+pTable x = typ+ where+ name = Ct.between (Ct.before x '{') ('(',')') --table(name) or list(name) gets name.+ typ = (name,if Ct.before x '{' `Ac.contains` "table" then Table (parseTables body) else List body) -- Determines what kind of type the Quill is.+ body = Md.splitOn (En.encompassing x ('{','}')) ';' + quoted y = if ('`','\'') `Ac.surrounds` y then En.encompassing x ('`','\'') else Ct.remove y ' ' -- Whole String encapsulation+ parseTables = map (\y -> (quoted $ Ct.before y ':', Ct.after y ':'))++-- | Turn the lines of a file into a list of tables, AKA a Database.+pFile :: [String] -> [Quill]+pFile x = map pTable $ Md.splitOn (prepare x) '}'+++
+ Cookbook/Project/Quill2/Q2Prelude.hs view
@@ -0,0 +1,23 @@+{- |+ Module : Cookbook.Project.Quill2.Q2Prelude+ Copyright : (c) 2014 by Nate Pisarski+ License : BSD3+ Maintainer : nathanpisarski@gmail.com+ Stability : Stable+ Portability : Portable (Cookbook)+Q2Prelude is the entry-level module for Quill2. It defines the data types that define data, databases, and errors throughout the rest of Quill2.+-}++module Cookbook.Project.Quill2.Q2Prelude where+ +-- | The body of a table or list.+data Element a = List [a] | Table [(a,a)] deriving (Eq, Show)++-- | Helper type. Binds a name to a body.+type Quill = (String,Element String)++-- | Encapsulates errors in the quill database. Currently supports Missing elements and Multiple Instances.+data QuillStatus a = QuillSuccess a | QuillMissing String | QuillMultiple String deriving (Eq, Show)++-- | Safe way of adding items to a Quill database. Allows type-checking on Lists and Tables when manipulating Elements.+data QuillAddition = AList (String, String) | ATable (String, String, String) deriving (Eq, Show)
Cookbook/Recipes/Algorithm.hs view
@@ -11,7 +11,6 @@ module Cookbook.Recipes.Algorithm where import Cookbook.Recipes.DataStructures-import Cookbook.Ingredients.Lists.Modify -- | Get every node of a tree, put it into a list. climb :: Tree a -> [a]@@ -23,14 +22,14 @@ treeMap :: Tree a -> (a -> a) -> Tree a treeMap tr f = case tr of Empty -> Empty- (Branch a Empty z@(Branch c _ _)) -> Branch (f c) (treeMap z f) Empty- (Branch a z@(Branch b _ _) Empty) -> Branch (f b) Empty $ treeMap z f+ (Branch _ Empty z@(Branch c _ _)) -> Branch (f c) (treeMap z f) Empty+ (Branch _ z@(Branch b _ _) Empty) -> Branch (f b) Empty $ treeMap z f -- | Collectively nullify nodes on a tree. treeFilter :: Tree a -> (a -> Bool) -> Tree a-treeFilter Empty f = Empty-treeFilter (Branch a Empty z@(Branch b _ _)) f = if f a then Branch a Empty (treeFilter z f) else Empty-treeFilter (Branch a z@(Branch b _ _) Empty) f = if f a then Branch a (treeFilter z f) Empty else Empty+treeFilter Empty _ = Empty+treeFilter (Branch a Empty z@(Branch _ _ _)) f = if f a then Branch a Empty (treeFilter z f) else Empty+treeFilter (Branch a z@(Branch _ _ _) Empty) f = if f a then Branch a (treeFilter z f) Empty else Empty -- | Generates a list of points, with the specified null data in the snd of the tupples. genMatrix :: (Int,Int) -> a -> [((Int,Int),a)]
Cookbook/Recipes/Cline.hs view
@@ -1,7 +1,6 @@ module Cookbook.Recipes.Cline(parse,Cline(..),clineExtract,clArg) where import qualified Cookbook.Essential.Continuous as Ct-import qualified Cookbook.Essential.Common as Cm import qualified Cookbook.Ingredients.Lists.Modify as Md import qualified Cookbook.Ingredients.Lists.Access as Ac import qualified Cookbook.Recipes.Sanitize as Sn@@ -20,8 +19,11 @@ data Cline = Flag Char | Argument String String deriving (Show,Eq) -- | Parses a flag argument.+singleParse :: String -> Cline singleParse y = Flag (last y)+ -- | Parses an argument Cline.+doubleParse :: (String, String) -> Cline doubleParse (a,b) = Argument (Ct.after a "--") b -- | Extract arguments from a list of word-separated strings.@@ -30,12 +32,14 @@ (a:b:[]) -> if Ac.count a '-' == 2 then [doubleParse (a,b)] else [singleParse a,singleParse b] (a:[]) -> [singleParse a] _ -> helper x- ++-- | Helps clineExtract. Determines whether to single or double parse something+helper :: [String] -> [Cline] helper x | Ac.count w1 '-' == 1 = singleParse w1 : clineExtract (w2:r) | Ac.count w1 '-' == 2 = doubleParse (w1,w2) : clineExtract r | otherwise = clineExtract (w2:r)- where (w1:w2:r) = x+ where (w1:w2:r) = x -- | Parse a flat string into a list of Clines. parse :: String -> [Cline]
Cookbook/Recipes/Math.hs view
Cookbook/Recipes/Meta.hs view
@@ -2,12 +2,10 @@ module Cookbook.Recipes.Cline, module Cookbook.Recipes.DataStructures, module Cookbook.Recipes.Math,- module Cookbook.Recipes.Sanitize,- module Cookbook.Recipes.WordStats) where+ module Cookbook.Recipes.Sanitize) where import Cookbook.Recipes.Algorithm import Cookbook.Recipes.Cline import Cookbook.Recipes.DataStructures import Cookbook.Recipes.Math import Cookbook.Recipes.Sanitize-import Cookbook.Recipes.WordStats
Cookbook/Recipes/Sanitize.hs view
cookbook.cabal view
@@ -3,9 +3,9 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 2.3.4.5-synopsis: Tiered general-purpose libraries with domain-specific applications.-description: Cookbook is a line of libraries covering a wide variety of Haskell applications. Every application that I make, I add its functions to Cookbook, turning Cookbook into an all-encompassing general-purpose library over time. The claim-to-fame for the library is its use of overloaded typeclasses, called "Continuities". +version: 3.0.1.1+synopsis: Tiered general-purpose libraries with domain-specific applications.+description: Cookbook is a line of libraries covering a wide variety of Haskell applications. Every application that I make, I add its functions to Cookbook, turning Cookbook into an all-encompassing general-purpose library over time. The claim-to-fame for the library is its use of overloaded typeclasses, called "Continuities". license: BSD3 license-file: LICENSE author: Nate Pisarski@@ -16,8 +16,43 @@ build-type: Simple cabal-version: >=1.8 library - exposed-modules: Cookbook.Essential.Common, Cookbook.Essential.Continuous, Cookbook.Essential.IO, Cookbook.Project.Configuration.Configuration, Cookbook.Project.Preprocess.Preprocess, Cookbook.Ingredients.Functional.Break, Cookbook.Ingredients.Lists.Access, Cookbook.Ingredients.Lists.Modify, Cookbook.Ingredients.Lists.Stats, Cookbook.Ingredients.Tupples.Look, Cookbook.Ingredients.Tupples.Assemble, Cookbook.Recipes.Sanitize, Cookbook.Recipes.Math,Cookbook.Recipes.DataStructures,Cookbook.Recipes.Algorithm, Cookbook.Project.Quill.Quill, Cookbook.Recipes.Cline, Cookbook.Ingredients.Lists.Encompass, Cookbook.Project.Quill.Quill2.Q2Parse, Cookbook.Project.Quill.Quill2.Q2Prelude, Cookbook.Project.Quill.Quill2.Q2Api, Cookbook.Project.Quill.Quill2.Q2Io, Cookbook.Essential.Meta, Cookbook.Ingredients.Meta, Cookbook.Ingredients.Lists.Meta, Cookbook.Ingredients.Tupples.Meta, Cookbook.Ingredients.Functional.Meta, Cookbook.Recipes.Meta, Cookbook.Project.Quill.Quill2.Meta, Cookbook.Meta- build-depends: base ==4.6.*, directory, strict+ exposed-modules: + Cookbook.Meta,+ Cookbook.Essential.Common, + Cookbook.Essential.Continuous, + Cookbook.Essential.IO,+ Cookbook.Essential.Meta,+ + Cookbook.Ingredients.Functional.Break, + Cookbook.Ingredients.Lists.Access, + Cookbook.Ingredients.Lists.Modify,+ Cookbook.Ingredients.Lists.Stats,+ Cookbook.Ingredients.Tupples.Look, + Cookbook.Ingredients.Tupples.Assemble, + Cookbook.Ingredients.Lists.Encompass, + Cookbook.Ingredients.Meta, + Cookbook.Ingredients.Lists.Meta, + Cookbook.Ingredients.Tupples.Meta, + Cookbook.Ingredients.Functional.Meta, ++ Cookbook.Recipes.Sanitize, + Cookbook.Recipes.Math,+ Cookbook.Recipes.DataStructures,+ Cookbook.Recipes.Algorithm, + Cookbook.Recipes.Cline, + Cookbook.Recipes.Meta, ++ Cookbook.Project.Configuration.Configuration,+ Cookbook.Project.Preprocess.Preprocess, + Cookbook.Project.Quill2.Q2Parse, + Cookbook.Project.Quill2.Q2Prelude, + Cookbook.Project.Quill2.Q2Api, + Cookbook.Project.Quill2.Q2Io, + Cookbook.Project.Quill2.Meta+ + + build-depends: base ==4.*, directory, strict+ source-repository head type: git location: https://github.com/natepisarski/Cookbook-hs