Skip to content

Commit

Permalink
Break up cabal project and module structure.
Browse files Browse the repository at this point in the history
  • Loading branch information
solomon-b committed Dec 11, 2022
1 parent 5d459bd commit 4aa9918
Show file tree
Hide file tree
Showing 35 changed files with 884 additions and 694 deletions.
62 changes: 17 additions & 45 deletions cofree-bot.cabal → chat-bots-contrib/chat-bots-contrib.cabal
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cabal-version: 3.0
name: cofree-bot
name: chat-bots-contrib
version: 0.1.0.0
synopsis: A library for building bots compositionally.
synopsis: Bot behavior and Server modules for the chat-bots library.
bug-reports: https://github.com/cofree-coffee/cofree-bot
license: MIT
author: Solomon, Asad, and the Cofree-Coffee community
Expand Down Expand Up @@ -57,31 +57,6 @@ common common-libraries
, these
, typed-process

executable cofree-bot
import:
, common-libraries
, common-settings

main-is: Main.hs
hs-source-dirs: app
build-depends:
, aeson
, barbies
, cofree-bot
, directory
, filepath
, mtl
, optparse-applicative
, xdg-basedir
, yaml

other-modules:
, Options
, Options.Env
, Options.Config
, Options.Types
, Options.Parser

--------------------------------------------------------------------------------

library
Expand All @@ -91,27 +66,22 @@ library

hs-source-dirs: src
exposed-modules:
CofreeBot
CofreeBot.Bot
CofreeBot.Bot.Behaviors
CofreeBot.Bot.Behaviors.Calculator
CofreeBot.Bot.Behaviors.Calculator.Language
CofreeBot.Bot.Behaviors.CoinFlip
CofreeBot.Bot.Behaviors.GHCI
CofreeBot.Bot.Behaviors.Hello
CofreeBot.Bot.Behaviors.Jitsi
CofreeBot.Bot.Behaviors.Jitsi.Dictionary
CofreeBot.Bot.Behaviors.Magic8Ball
CofreeBot.Bot.Behaviors.Updog
CofreeBot.Bot.Context
CofreeBot.Utils
CofreeBot.Utils.ListT
Parsing
Data.Chat.Bot.Calculator
Data.Chat.Bot.Calculator.Language
Data.Chat.Bot.CoinFlip
Data.Chat.Bot.GHCI
Data.Chat.Bot.Hello
Data.Chat.Bot.Jitsi
Data.Chat.Bot.Jitsi.Dictionary
Data.Chat.Bot.Magic8Ball
Data.Chat.Bot.Updog
Data.Chat.Server.Matrix

build-depends:
, aeson
, attoparsec
, containers
, chat-bots
, data-fix
, directory
, hint
Expand All @@ -122,12 +92,13 @@ library
, pretty-simple
, process
, random
, transformers
, vector
, xdg-basedir

--------------------------------------------------------------------------------

test-suite cofree-bot-test
test-suite chat-bots-contrib-test
import:
, common-libraries
, common-settings
Expand All @@ -138,7 +109,8 @@ test-suite cofree-bot-test

build-depends:
, attoparsec
, cofree-bot
, chat-bots
, chat-bots-contrib
, data-fix
, hspec
, hspec-core
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
module CofreeBot.Bot.Behaviors.Calculator
module Data.Chat.Bot.Calculator
( calculatorBot,
simplifyCalculatorBot,
printCalcOutput,
module Language,
)
where

--------------------------------------------------------------------------------

import CofreeBot.Bot
import CofreeBot.Bot.Behaviors.Calculator.Language
import CofreeBot.Utils
import Control.Monad.Reader
import Control.Monad.State
import Data.Chat.Bot
import Data.Chat.Bot.Calculator.Language as Language
import Data.Chat.Bot.Monoidal
import Data.Chat.Utils
import Data.Profunctor
import Data.Text qualified as T
import Data.Text (Text)
import Data.Text qualified as Text

--------------------------------------------------------------------------------

Expand All @@ -22,7 +25,7 @@ calculatorBot = do
statement <- ask
state $ execCalculator statement

parseErrorBot :: Monad m => Bot m s ParseError T.Text
parseErrorBot :: Monad m => Bot m s ParseError Text
parseErrorBot = pureStatelessBot $ \ParseError {..} ->
"Failed to parse msg: \""
<> parseInput
Expand All @@ -33,12 +36,12 @@ parseErrorBot = pureStatelessBot $ \ParseError {..} ->
simplifyCalculatorBot ::
Monad m =>
Bot m s Statement (CalcError \/ CalcResp) ->
Bot m s T.Text T.Text
Bot m s Text Text
simplifyCalculatorBot bot =
dimap parseStatement indistinct $ parseErrorBot \/ rmap printCalcOutput bot

printCalcOutput :: Either CalcError CalcResp -> T.Text
printCalcOutput :: Either CalcError CalcResp -> Text
printCalcOutput = \case
Left err -> T.pack $ show err
Left err -> Text.pack $ show err
Right Ack -> "*variable saved*"
Right (Log e n) -> T.pack $ show e <> " = " <> show n
Right (Log e n) -> Text.pack $ show e <> " = " <> show n
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{-# LANGUAGE CPP #-}
{-# OPTIONS -fdefer-typed-holes -Wno-orphans #-}
{-# LANGUAGE RankNTypes #-}

module CofreeBot.Bot.Behaviors.Calculator.Language where
module Data.Chat.Bot.Calculator.Language where

import CofreeBot.Utils
import Control.Applicative
import Control.Monad.Error.Class
import Control.Monad.Except
Expand All @@ -15,16 +15,21 @@ import Data.Char
( isAlpha,
isDigit,
)
import Data.Foldable
import Data.Chat.Utils
#if __GLASGOW_HASKELL__ >= 902
#else
import Data.Foldable (asum)
#endif
import Data.Functor
import Data.List.NonEmpty qualified as NE
import Data.Map.Strict qualified as Map
import Data.Text qualified as T
import Data.Text (Text)
import Data.Text qualified as Text

--------------------------------------------------------------------------------
-- Utils

infixOp :: Parser a -> Parser b -> Parser T.Text -> Parser (a, b)
infixOp :: Parser a -> Parser b -> Parser Text -> Parser (a, b)
infixOp p1 p2 pop =
"("
|*| p1
Expand All @@ -38,7 +43,7 @@ infixOp p1 p2 pop =
--------------------------------------------------------------------------------
-- Parsing types

type VarName = T.Text
type VarName = Text

data Expr
= Var VarName
Expand All @@ -48,7 +53,7 @@ data Expr
| Neg Expr

data Statement
= Let T.Text Expr
= Let Text Expr
| StdOut Expr
deriving (Show)

Expand All @@ -59,7 +64,7 @@ type Program = NE.NonEmpty Statement

instance Show Expr where
showsPrec p = \case
Var x -> shows $ T.unpack x
Var x -> shows $ Text.unpack x
Val n -> shows n
x `Add` y ->
showParen (p >= 6) $ (showsPrec 6 x) . (" + " ++) . (showsPrec 6 y)
Expand All @@ -72,7 +77,7 @@ instance Show Expr where

varNameP :: Parser VarName
varNameP =
fmap (uncurry T.cons) $ letter |*| A.takeWhile (liftA2 (||) isAlpha isDigit)
fmap (uncurry Text.cons) $ letter |*| A.takeWhile (liftA2 (||) isAlpha isDigit)

exprP :: Parser Expr
exprP =
Expand Down Expand Up @@ -111,25 +116,25 @@ programP =
-- $> parseOnly programP "x := ((11 + 12) + 13)\nx + 1"

data ParseError = ParseError
{ parseInput :: T.Text,
parseError :: T.Text
{ parseInput :: Text,
parseError :: Text
}

parseStatement :: T.Text -> Either ParseError Statement
parseStatement txt = first (ParseError txt . T.pack) $ parseOnly statementP txt
parseStatement :: Text -> Either ParseError Statement
parseStatement txt = first (ParseError txt . Text.pack) $ parseOnly statementP txt

parseProgram :: T.Text -> Either ParseError Program
parseProgram txt = first (ParseError txt . T.pack) $ parseOnly programP txt
parseProgram :: Text -> Either ParseError Program
parseProgram txt = first (ParseError txt . Text.pack) $ parseOnly programP txt

--------------------------------------------------------------------------------
-- Evaluator

data CalcResp = Log Expr Int | Ack

data CalcError = LookupError T.Text
data CalcError = LookupError Text.Text
deriving (Show)

type CalcState = Map.Map T.Text Int
type CalcState = Map.Map Text.Text Int

-- | Evaluate an expression in our arithmetic language
eval :: Expr -> ExceptT CalcError (State CalcState) Int
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
module CofreeBot.Bot.Behaviors.CoinFlip where
module Data.Chat.Bot.CoinFlip where

--------------------------------------------------------------------------------

import CofreeBot.Bot
import CofreeBot.Utils.ListT (emptyListT)
import Control.Monad.ListT (emptyListT)
import Control.Monad.Reader
import Data.Attoparsec.Text
import Data.Bifunctor (bimap)
import Data.Chat.Bot
import Data.Profunctor
import Data.Text qualified as T
import System.Random
import Data.Text (Text)
import Data.Text qualified as Text
import System.Random (randomIO)

--------------------------------------------------------------------------------

coinFlipBot :: Bot IO () () Bool
coinFlipBot = do
randomIO

simplifyCoinFlipBot :: forall s. Bot IO s () Bool -> TextBot IO s
simplifyCoinFlipBot :: forall s. Bot IO s () Bool -> Bot IO s Text Text
simplifyCoinFlipBot b = do
t <- ask
case to t of
Left _err -> Bot $ pure $ const emptyListT
Right _ -> dimap (const ()) from $ b
where
to :: T.Text -> Either T.Text ()
to = fmap (bimap T.pack id) $ parseOnly parseCoinFlipCommand
to :: Text -> Either Text ()
to = fmap (bimap Text.pack id) $ parseOnly parseCoinFlipCommand

from :: Bool -> T.Text
from :: Bool -> Text
from = \case
True -> "Coin Flip Result: True"
False -> "Coin Flip Result: False"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{-# LANGUAGE NumDecimals #-}

module CofreeBot.Bot.Behaviors.GHCI
module Data.Chat.Bot.GHCI
( ghciBot,
ghciConfig,
hGetOutput,
Expand All @@ -9,14 +9,16 @@ where

--------------------------------------------------------------------------------

import CofreeBot.Bot
import CofreeBot.Utils
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Loops (whileM)
import Data.Attoparsec.Text as A
import Data.Chat.Bot
import Data.Chat.Bot.Monoidal
import Data.Chat.Utils
import Data.Profunctor
import Data.Text qualified as T
import Data.Text (Text)
import Data.Text qualified as Text
import GHC.Conc (threadDelay)
import System.IO
import System.Process.Typed
Expand All @@ -26,19 +28,19 @@ import System.Process.Typed
hGetOutput :: Handle -> IO String
hGetOutput handle = whileM (hReady handle) (hGetChar handle)

ghciBot' :: Process Handle Handle () -> Bot IO () T.Text T.Text
ghciBot' :: Process Handle Handle () -> Bot IO () Text Text
ghciBot' p =
mapMaybeBot (either (const Nothing) Just . parseOnly ghciInputParser) $
Bot $
\s i -> do
o <- liftIO $ do
hPutStrLn (getStdin p) $ T.unpack i
hPutStrLn (getStdin p) $ Text.unpack i
hFlush (getStdin p)
void $ threadDelay 5e5
hGetOutput (getStdout p)
pure (T.pack o, s)
pure (Text.pack o, s)

ghciBot :: Process Handle Handle () -> Bot IO () T.Text T.Text
ghciBot :: Process Handle Handle () -> Bot IO () Text Text
ghciBot p =
dimap (distinguish (/= "ghci: :q")) indistinct $
pureStatelessBot (const $ "I'm Sorry Dave")
Expand All @@ -51,7 +53,7 @@ ghciConfig =
shell
"docker run -i --rm haskell 2>&1"

ghciInputParser :: Parser T.Text
ghciInputParser :: Parser Text
ghciInputParser = do
void $ "ghci: "
T.pack <$> many1 anyChar
Text.pack <$> many1 anyChar
Loading

0 comments on commit 4aa9918

Please sign in to comment.