Lately we’ve focused on some of the finer points of how to learn Haskell. But at a certain point we want to actually build things. This next series of articles will focus on some of the more practical aspects of Haskell. This week, I’m going to introduce one of my own Haskell projects. We’ll first examine some of the reasons I chose Haskell. Then we’ll look at how I’ve organized the project and some of the pros and cons of those choices. Introduction to One Week Apps The program I’ve created is called One Week Apps (Names have never been my strong suit…I’m open to better ideas). It is designed to help you . It allows you to specify important elements of your app in a simple domain specific language. As of current writing, the supported app features are: rapidly create mobile prototypes Colors Fonts Alert popups Programmer errors (think NSError) Localized strings View layouts Simple model objects. As an example, suppose you wanted to create an app from scratch and add a simple login screen. You’ll start by using the command to generate the XCode project itself. First you'll enter some information about the app though a command line prompt. Then it will generate the project as well as some directories for you to place your code. owa new >> owa newCreating new OWA project!What is the name of your app:>> Blog ExampleWhat is the prefix of your app (3 letters):>> BEXWhat is the author's name:>> JamesWhat is your company name (optional):>> Monday Morning HaskellYour new app "Blog Example" has been created! We then start specifying the different elements of our app. To represent colors, we’ll put the following code in a file in the generated directory. .colors app Color labelColor Hex 0x000000 Color fieldColor Hex 0xAAAAAA Color buttonColor Blue 255 Red 0 Green 0 We can also specify some different fonts for the elements on your screen: Font labelFont FontFamily HelveticaNeue Size 12.0 Styles Light Font fieldFont FontFamily Helvetica Size 16 Font buttonFont FontFamily Arial Size 24 Styles Bold Now we’ll add some localization to the strings: NAME_TITLE = “Name”“NAME_PLACEHOLDER” = “Enter Your Name”PASSWORD_TITLE = “Password”“PASSWORD_PLACEHOLDER” = “Enter Your Password”SUBMIT_BUTTON_TITLE = “Log In!” Finally, we’ll specify the view layout itself. We can use the colors and fonts we wrote above. We can also modify the layout of the different elements. View loginView Type BEXLoginView Elements Label nameLabel Text “NAME_TITLE” TextColor labelColor Font labelFont Layout AlignTop 40 AlignLeft 40 Height 30 Width 100 TextField nameField PlaceholderText “NAME_PLACEHOLDER” PlaceholderTextColor fieldColor PlaceholderFont fieldFont Layout Below nameLabel 20 AlignLeft nameLabel Height 30 Width 300 Label passwordLabel Text “PASSWORD_TITLE” TextColor labelColor Font labelFont Layout Below nameField 40 AlignLeft nameLabel Height 30 Width 100 TextField passwordField PlaceholderText “PASSWORD_PLACEHOLDER” PlaceholderTextColor fieldColor PlaceholderFont fieldFont Layout Below passwordLabel 40 AlignLeft nameLabel Height 30 Width 300 Button submitButton Text “SUBMIT_BUTTON_TITLE” TextColor buttonColor Font buttonFont Layout Below passwordField 40 CenterX Height 45 Width 200 Then we’ll run the command to generate the files. We need to add them manually to your XCode project (for now), but they should at least appear in the proper folder. Finally, we'll add a few simple lines of connecting code in the view controller: owa gen class ViewController: UIViewController { override func loadView() { view = BEXLoginView() }... And we can take a look at our basic view: Rationale For Haskell When I first came up with the idea for this project, I knew Haskell was a good choice. One major feature we should notice is the . It has . We read in a bunch of files at the start, and then write to a bunch of files at the very end. In between, all we have is the complicated business logic. We parse file contents and turn them into algebraic data structures. Then we perform more transformations on those depending on the chosen language (you can currently use Objective C or Swift). simple structure of the program limited IO boundaries There is little in the way of global state to track (at least now when there’s no “compiling” occurring). There are no database connections whatsoever. Many of the things that can make Haskell clunky to deal with (IO stuff and global state) aren’t present in the main body of the program. On the contrary, the body consists of computations playing to . These include string processing, representing data abstractly, an so on. These were the main criteria for choosing Haskell for this project. Of course, there are libraries to deal with all the “clunky” issues I mentioned earlier. But we don’t even need to learn those for this project. Haskell’s strengths Architecture Now I’ll give a basic overview of how I architected this program. I decided to go with a multi-package approach. We can see the different packages here in my file: stack.yaml packages: - './owa-core' - './owa-model' - './owa-utils' - './owa-parse' - './owa-objc' - './owa-swift' The section contains the datatypes for the objects of the mobile app. Other packages rely on this. model The package contains all code and tests related to parsing files. parse The package contains all code creating Objective C files and printing them out. It also has tests for these features. objc The package does the same for Swift code. swift The package handles functionality like the CLI, interpreting the commands, searching for files, and so on. core The package contains certain extra code needed by multiple packages. utils Pro and Cons Let’s look at some of the advantages and disadvantages of this architecture. As an alternative, we could have used a single-package structure. One advantage of the chosen approach is shorter compile time . There is a tradeoff with total compile time. Having many packages lead to more linking between libraries, which takes a while. However, once you’ve compiled the project once, each successive re-compile should take much less time. You’ll only be re-compiling the module you happen to be working on in most cases. This leads to a faster development cycle. In this case, the development cycle is more important than the overall compile time. If the program needed to be compiled from scratch on a deployment machine with some regularity, we might make a different choice. within the development cycle The is another important factor. It is now very obvious where you’ll want to add parsing code. If a feature seems broken, you know where to go to find a failing test or add in a new test to reproduce the bug. This system works far better than the haphazard version-based test organization I had earlier. organization of the code Another advantage I would list is it’s now a cleaner process to to support. To support a new language, there will be few changes necessary to the core module. You’ll add another package (say ) and add a few more options to Core. This should make it an easy repository to fork for, say, anyone who wanted to make an android version. add another language owa-android Let’s also consider some of the disadvantages. It is unlikely many of these packages will be used from one another. The module firmly depends on the package, for instance. The language specific modules will not interact with each other. But they're also not particularly useful unless you're using the parser anyways. in total isolation owa-parse owa-model Additionally, the module is a real eyesore. It has a few random utilities needed by the testing code for several packages as well as the printing code. It seems to suggest there should only be one package for testing, but I find this to be unsatisfactory. It suggests instead there should be common printing code. It may be a reasonable solution to simply leave this code duplicated in certain places. This is another code-smell. But if different languages evolve separately, then their utility code might also. utils Summary So what did we learn about Haskell from this project? Haskell is great at internal processing. But programs with wide IO bounds can cause some headaches. Luckily, One Week Apps has lots of internal processing, but limited IO bounds. So Haskell was a natural choice. Meanwhile, multi-package organization has some advantages in terms of code organization. But it can also lead to some headaches as far as placing common code. is now open source, so feel free to check it out on ! Do you love the idea and think it would supercharge your app-writing? You should contact me and check out our page! One Week Apps Github issues Want to contribute but have never touched Haskell? You’re in luck, because we’ve got a couple great resources for getting started! First, you should check out our . It’ll walk you through some of the basic steps for installing Haskell. It’ll also show you some awesome resources to kickstart your Haskell code writing. Getting Started Checklist If you have a little experience but want more practice, you should download our . It’ll teach you about recursion, a fundamental functional paradigm. It also has some practice problems to get you learning! Recursion Workbook