diff --git a/.gitignore b/.gitignore index 2d4daa4..267a74c 100755 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ .idea* +fenv +*.o +*.hi diff --git a/12-functors-applicative-functors-and-monoids.hs b/12-functors-applicative-functors-and-monoids.hs new file mode 100644 index 0000000..8a461b6 --- /dev/null +++ b/12-functors-applicative-functors-and-monoids.hs @@ -0,0 +1,18 @@ +-- Functor: +-- :t (replicate 3) +(replicate 3) :: a -> [a] + +-- :t fmap (replicate 3) +(fmap (replicate 3)) :: f a -> f [a] + +-- We say that (replicate 3) has been "lifted" to f + +-- Also think of functors as things that output values. +-- fmap'ing a functor is attaching a modifier to the output(s) of the functor +-- partial applications of a function are themselves functors +-- fmap'ing these partial applications results in composition! + +-- Applicative functors - Applicative class in Haskell +class (Functor f) => Applicative f where + pure :: a -> f a + (<*>) :: f (a -> b) -> (f a -> f b) diff --git a/fenv.hs b/fenv.hs index 6cdef91..7c17499 100644 --- a/fenv.hs +++ b/fenv.hs @@ -1,6 +1,7 @@ import System.Environment import System.Directory import System.IO +import System.Exit (exitSuccess,exitFailure) import Data.List type EnvKey = String @@ -11,23 +12,49 @@ data EnvFile = | Entry EnvKey EnvValue EnvFile deriving (Show,Eq,Read) -dispatch :: [(String, [String] -> IO ())] -dispatch = [ - ("get", cliGet), - ("set", cliSet), - ("unset", cliUnset) - ] - main = do - let f = (Entry "foo" "bar" End) - putStrLn (show f) + args <- getArgs + cliRun args + +cliRun :: [String] -> IO () +cliRun ("get":args) = cliGet args +cliRun ("set":args) = cliSet args +cliRun ("unset":args) = cliUnset args +cliRun ("list":_) = cliList +cliRun _ = cliFail "USAGE: fenv [...args]" cliGet :: [String] -> IO () cliGet (name:_) = do env <- getEnvFile case (getEntry env name) of (Just value) -> putStrLn value - Nothing -> putStrLn "ERROR: No value defined" + Nothing -> cliFail "ERROR: No value defined" +cliGet _ = cliFail "USAGE: fenv get " + +cliUnset :: [String] -> IO () +cliUnset (name:_) = do + env <- getEnvFile + let env' = (removeEntry env name) in + replaceEnvFile env' +cliUnset _ = cliFail "USAGE: fenv unset " + +cliSet :: [String] -> IO () +cliSet (name:value:_) = do + env <- getEnvFile + let env' = (setEntry env name value) in + replaceEnvFile env' +cliSet _ = cliFail "USAGE: fenv set " + +cliList :: IO () +cliList = do + env <- getEnvFile + printLevel env + where + printLevel (Entry key value rest) = putStrLn (key ++ ": " ++ value) >>= (printLevel rest) + printLevel End = return () + +cliFail :: String -> IO () +cliFail message = putStrLn message >>= return exitFailure setEntry :: EnvFile -> EnvKey -> EnvValue -> EnvFile setEntry env key value = let env'=(removeEntry env key) in @@ -58,7 +85,8 @@ getEnvFile :: IO EnvFile getEnvFile = do path <- getEnvFilePath contents <- readFile path - return $ read contents + if contents == "" then return End + else return $ read contents getEnvFilePath :: IO FilePath getEnvFilePath = do