Skip to content

Instantly share code, notes, and snippets.

@TrevorBasinger
Last active August 29, 2015 14:11
Show Gist options
  • Select an option

  • Save TrevorBasinger/b092bd6e4ebd612f8a52 to your computer and use it in GitHub Desktop.

Select an option

Save TrevorBasinger/b092bd6e4ebd612f8a52 to your computer and use it in GitHub Desktop.
module Test where
import Data.Foldable (traverse_)
import Control.Monad.Eff
import Control.Monad.State
import Control.Monad.State.Class
import Control.Monad.State.Trans
import Control.Monad.Reader
import Control.Monad.Reader.Class
import Control.Monad.Writer
import Control.Monad.Writer.Class
import Control.Monad.Writer.Trans
import Control.Monad.Trans
import Control.Monad.Error
import Control.Monad.Error.Class
import Control.Monad.Error.Trans
import Data.Identity
import Math
import Data.String (split)
import Data.Array
import Data.Maybe
import Data.Monoid
import Data.Monoid.Sum
import Data.Traversable
import Data.Foldable
import Data.Tuple
import Debug.Trace
import Data.Either
fmap = (<$>)
-- State Exercises
sumArray :: [Number] -> State Number Unit
sumArray = traverse_ $ \n -> modify (\sum -> sum + n )
paramValue :: String -> Number
paramValue "(" = 1
paramValue ")" = -1
paramValue _ = 0
isZero :: Number -> Boolean
isZero 0 = true
isZero _ = false
testState :: Number -> Number -> Number
testState x y | y >= 0 = x + y
testState _ _ = -1
testParens :: String -> Boolean
testParens = isZero <<< flip execState 0 <<< traverse_ (\c -> modify $ testState (paramValue c) ) <<< split ""
-- Reader Exercises
type Level = Number
type Doc = Reader Level String
addIndent :: Number -> String
addIndent 0 = ""
addIndent n = "\t" ++ addIndent n
line :: String -> Doc
line str = do
l <- ask
return $ addIndent l ++ str ++ "\n"
indent :: Doc -> Doc
indent = local ((+) 1)
cat :: [Doc] -> Doc
cat xss = do
arr <- sequence xss
return $ foldMap id arr
render :: Doc -> String
render = flip runReader 0
-- Writer Exercises
logNum :: Number -> Writer [String] Sum
logNum n = do
tell ["Logging num: " ++ show n]
return $ Sum n
sumArray' :: [Number] -> Writer [String] Sum
sumArray' = fmap (foldMap id) <<< sequence <<< fmap logNum
isEven :: Number -> Boolean
isEven n = n % 2 == 0
collatz :: Number -> Writer [Number] Number
collatz 1 = do
tell [1]
return 1
collatz n | isEven n = do
tell [ n ]
collatz $ n / 2
collatz n | not $ isEven n = do
tell [ n ]
collatz $ 3 * n + 1
-- Error Exercises
writerAndErrorT :: ErrorT String (Writer [String]) String
writerAndErrorT = do
tell ["Before the error"]
--throwError "Error!"
tell ["After the error"]
return "RetVal"
type Parser = StateT String (WriterT [String] (ErrorT String Identity))
{-
split' :: Parser String
split' = do
s <- get
lift $ tell ["The state is " ++ show s]
case s of
"" -> lift $ lift $ throwError "Empty String"
_ -> do
put (drop 1 s)
return (take 1 s)
-}
--runParser :: Parser -> String
--runParser = runIdentity <<< runErrorT <<< runWriterT <<< runStateT
type ErrorVal = ErrorT String Identity
safeDivide' :: Number -> Number -> ErrorVal Number
safeDivide' a b | a % b == 0 = return $ a / b
safeDivide' _ _ = throwError "Can't divide safely"
main :: forall eff. Eff ( trace :: Trace | eff) Unit
main = do
--trace "Hello World"
--trace $ show <<< runSum <<< (foldMap id) <<< fst $ runWriter $ sequence $ logNum <$> [1,2,3,4,5,6,7,8,9]
--trace $ show <<< runWriter $ sumArray' [1,2,3,4,5,6,7,8,9]
--trace $ show <<< foldr max 0 <<< snd <<< runWriter $ collatz 108
--trace $ show <<< length <<< snd <<< runWriter $ collatz 108
--trace <<< show $ runWriter $ runErrorT writerAndErrorT
trace <<< show $ runErrorT $ safeDivide' 300 50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment