DEV Community

Cover image for Understanding Triggers in NeoHaskell: A Gateway to Event-Driven Programming
Nick Tchayka for NeoHaskell

Posted on

Understanding Triggers in NeoHaskell: A Gateway to Event-Driven Programming

Since the release of NeoHaskell v0.3.0, we've noticed some confusion about what Triggers are and how they can be useful in real-world applications. In this post, we'll dive deeper into the concept of Triggers and explore their potential in various scenarios.

What are Triggers?

At their core, Triggers in NeoHaskell are entry points to your application where external agents can generate events in your service. They act as a bridge between the outside world and your application's event loop.

The Simplest Trigger: Time

Let's start with the simplest example we provided in our release notes:

tickTrigger :: Trigger TickEvent
tickTrigger = Time.triggerEveryMilliseconds 1000 (\_ -> Tick)
Enter fullscreen mode Exit fullscreen mode

This Trigger generates a Tick event in your application every 1000 milliseconds. While simple, it demonstrates the key concept: an external factor (in this case, the passage of time) is causing events to occur in your application.

Let's take a look at hypothetical triggers that could be implemented (they do not exist at the time of writing this, but they will be probably implemented in future versions).

Beyond Time: HTTP Servers

Triggers are far more powerful than just timers. Let's look at how they could be used to create an HTTP server:

postFooTrigger :: Trigger MyEvent
postFooTrigger = HTTP.trigger ANON
  { method = HTTP.POST,
    route = "/foo",
    handler = \_ -> MyEvent
  }
Enter fullscreen mode Exit fullscreen mode

In this example, we're creating a Trigger that listens for POST requests to the "/foo" endpoint. Whenever a request is received, it generates a MyEvent in your application. This is how Triggers facilitate building HTTP servers: they provide a way for incoming HTTP requests to generate events in your application's event loop.

More Real-World Examples

Triggers aren't limited to just time and HTTP. Here are a few more examples to illustrate their versatility:

  1. Chat Bot:
   discordMessageTrigger :: Trigger ChatEvent
   discordMessageTrigger = Discord.onMessage \msg -> 
     NewMessage ANON { author = msg.author, content = msg.content }
Enter fullscreen mode Exit fullscreen mode

This Trigger would generate a NewMessage event every time a message is received in a Discord channel.

  1. File System Watcher:
   fileChangeTrigger :: Trigger FileEvent
   fileChangeTrigger = FileSystem.onChange "/path/to/watch" \change ->
     FileChanged ANON { path = change.path, type = change.type }
Enter fullscreen mode Exit fullscreen mode

This Trigger would generate a FileChanged event whenever files in the specified directory are modified.

  1. Database Listener:
   dbChangeTrigger :: Trigger DBEvent
   dbChangeTrigger = Database.onUpdate "users" \update ->
     UserUpdated ANON { id = update.id, fields = update.changedFields }
Enter fullscreen mode Exit fullscreen mode

This Trigger would generate a UserUpdated event whenever a record in the "users" table is updated.

Why Triggers Matter

Triggers are crucial because they allow your NeoHaskell application to react to the outside world in a structured, functional manner. They provide a clean separation between:

  1. How external events are received (the Trigger)
  2. How those events are represented in your application (the Event)
  3. How your application responds to those events (the Update function)

This separation makes it easier to reason about your application's behavior, test individual components, and modify or extend functionality over time.

Conclusion

Triggers in NeoHaskell are a powerful abstraction that enable truly event-driven programming. Whether you're building a simple CLI tool with a timer, a web server handling HTTP requests, a chat bot responding to messages, or a complex system reacting to database changes and file system events, Triggers provide a consistent, functional approach to handling external inputs.

We're excited to see what the NeoHaskell community builds with Triggers. If you have any questions or want to share what you're working on, join us on Discord or GitHub. Happy coding!

Top comments (0)