Announcing NeoHaskell v0.2.0: Bringing Elm-Inspired Architecture to CLI Apps
Nick Tchayka
Posted on July 27, 2024
We're excited to announce the release of NeoHaskell v0.2.0! This version marks a significant milestone in our journey to create a more accessible and powerful Haskell-based language. With this release, we're introducing a basic scaffolding for CLI applications inspired by Elm's architecture, along with substantial enhancements to our core library.
The Elm-Inspired CLI Architecture
One of the most exciting features in v0.2.0 is the introduction of, an Elm-inspired, event sourcing architecture for building CLI applications. This approach brings the clarity and maintainability of Elm's design to the world of command-line tools.
This architecture allows developers to create CLI apps with a clear separation of concerns, making it easier to reason about application state and user interactions.
Let's look at an example of how to build a simple CLI app:
module SimpleTodo (main) where
import Core
import Command qualified
import Platform qualified
type Model =
Record
'[ "todos" := Array Text,
"currentInput" := Text
]
data Message
= AddTodo
| UpdateInput Text
| RemoveTodo Int
| NoOp
deriving (Show)
init :: (Model, Command Message)
init =
let initialModel =
ANON
{ todos = [],
currentInput = ""
}
in (initialModel, Command.none)
update :: Message -> Model -> (Model, Command Message)
update message model =
case message of
AddTodo ->
if Text.isEmpty model.currentInput
then (model, Command.none)
else
( model
{ todos = Array.push model.currentInput model.todos,
currentInput = ""
},
Command.none
)
UpdateInput newInput ->
(model {currentInput = newInput}, Command.none)
RemoveTodo index ->
( model {todos = Array.removeAt index model.todos},
Command.none
)
NoOp ->
(model, Command.none)
view :: Model -> Text
view model = do
let todoList = Text.joinWith "\n" model.todos
let header = "Todo List:\n"
let footer = "\nCurrent input: " ++ model.currentInput
header ++ todoList ++ footer
main :: IO ()
main = Platform.init (ANON {init = init, view = view, update = update})
This example demonstrates the key components of the Elm-inspired architecture:
-
Model
: Represents the application state -
Message
: Defines the possible events in the application -
init
: Sets up the initial model and commands -
update
: Handles state transitions based on messages -
view
: Renders the current state as text -
main
: Initializes the application using thePlatform
module
Expanded Core Library
We've significantly enhanced our core library to provide more powerful tools for NeoHaskell developers:
- New concurrency primitives:
Channel
,Var
, andConcurrentVar
-
AsyncIO
module for handling asynchronous operations - Extended
Array
module with useful functions likeflatMap
andforEach
-
Version
module for parsing and working with semantic versions - The
Unknown
type for handling dynamic typing scenarios - A
Record
module for working with extensible records - New
Json
andYaml
modules for data serialization - An
OptionsParser
module to simplify CLI argument parsing - A
Console
module with built-in debugging capabilities
Trait System Enhancements
We've reorganized and expanded our trait system to provide a more cohesive and powerful set of abstractions:
- Improved
Appendable
,Applicable
, andCombinable
traits - A new
ToText
trait for consistent string conversion across types
Get Involved
We're excited to see what the community builds with NeoHaskell v0.2.0! Here's how you can get started:
- Check out our GitHub repository for the latest code
- Join our Discord community to discuss ideas and get help
- Try building a small CLI app and share your experience
Your feedback and contributions are crucial as we continue to evolve NeoHaskell. Let's work together to create a more accessible and powerful development experience!
Happy coding!
Nick
Posted on July 27, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
July 27, 2024