Docs
This commit is contained in:
parent
ad7290e705
commit
092bde3987
69
README.md
Normal file
69
README.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Bot framework
|
||||||
|
|
||||||
|
We had a discussion at work on Haskells suitability for Flowdock bots. The
|
||||||
|
argument was that if we want contributors outside of our Haskell team, we can't
|
||||||
|
use Haskell for the bot.
|
||||||
|
|
||||||
|
My counterargument was that Haskell allows you to write such code that we
|
||||||
|
present the beatiful pure core to the contributors, while keeping the ugly
|
||||||
|
side-effectful world on the edges.
|
||||||
|
|
||||||
|
This repository is an initial test of the ideas I had during the argument.
|
||||||
|
|
||||||
|
# Bot architecture
|
||||||
|
|
||||||
|
## Bot library
|
||||||
|
|
||||||
|
The core idea behind the architecture is having a tagless final (assuming I
|
||||||
|
understand this term) DSL specifying what the bot can do. It's then up to the
|
||||||
|
interpreter to figure out how to actually run the logic. I have separated the
|
||||||
|
library into two conceptual sections, **extensions** and **core bot features**.
|
||||||
|
All of the modules in the library should have Safe Haskell extension enabled.
|
||||||
|
|
||||||
|
The extensions have a limited subset of tagless final interpreters available
|
||||||
|
for it. This is in comparison to the core bot functionality which has error
|
||||||
|
handling and networking features as well. The two feature sets are defined in
|
||||||
|
`MonadBot` and `MonadExtension` constraints. See [DSL.hs](src/Bot/DSL.hs) for
|
||||||
|
the functionalities. It is up to the core contributors to add more tagless
|
||||||
|
final monads if more features are needed for the extensions.
|
||||||
|
|
||||||
|
Each extension is a type `Extension meta` which defines the actuator for the
|
||||||
|
extension of type `MonadExtension m => Request meta -> m (Maybe (Response
|
||||||
|
meta))`. You can read this type as a function from bot input into a possible
|
||||||
|
action (response). The meta field is just a interpeter specific (flowdock, irc,
|
||||||
|
slack) meta field which can contain for example event types or target channels.
|
||||||
|
|
||||||
|
The core bot is defined in the [Lib.hs](src/Bot/Lib.hs) file. This
|
||||||
|
implementation isn't most likely a good production quality implementation, but
|
||||||
|
shows a somewhat robust and clean implementation of a bot main loop. The nitty
|
||||||
|
gritty details of the networking stack is delegated to the `MonadNetwork`
|
||||||
|
interpreter. This could be for example reading and writing from a socket in
|
||||||
|
case of IRC bot, or reading from a `TChan` and writing to http in case of
|
||||||
|
Flowdock.
|
||||||
|
|
||||||
|
```
|
||||||
|
src/Bot
|
||||||
|
├── DSL
|
||||||
|
│ ├── Network.hs
|
||||||
|
│ ├── State.hs
|
||||||
|
│ └── Time.hs
|
||||||
|
├── DSL.hs
|
||||||
|
├── Extension.hs
|
||||||
|
├── Lib.hs
|
||||||
|
└── Log.hs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Demo application
|
||||||
|
|
||||||
|
The demo application is just reading from stdin and writing to stdout. You can
|
||||||
|
see the interpreter implementation in the [AppM.hs](src/AppM.hs) module. All
|
||||||
|
the nitty gritty details of the protocol specific implementation is done in
|
||||||
|
this module. As a sidenote, the `MonadData` instance is not working, I didn't
|
||||||
|
bother adding a sqlite / acid-state / whatever dependency.
|
||||||
|
|
||||||
|
Extensions are collected in the [Extensions.hs](src/Extensions.hs) file which
|
||||||
|
is just a list of extensions with a suitable meta-type. The actual extensions
|
||||||
|
are implemented in the [Extension](src/Extension) namespace. A [hello
|
||||||
|
world](src/Extension/Hello.hs) implementation is provided as an example. I have
|
||||||
|
tried having the set of ghc extensions on the extension modules as small as
|
||||||
|
possible.
|
Loading…
Reference in New Issue
Block a user