Authors: Lironne, Mahbod, Eylul
What is the problem?
For the project, we are implementing a fast and functional image editing user interface, that allows for more efficient and flexible image processing. The final result will be an abstract editor that can convert images based on different convolutions. We will be using the Haskell Image Processing Library (HIP).
What is the something extra?
We will include a user friendly GUI that allows for the import and export of several files, with the ability to select one or multiple editing styles to apply to the image. Our feature set will include image compression, colour reassignment, and blurring of the image.
Tentatively, we also will attempt to use Haskell’s provided neural library to implement style transfer if time permits
What did we learn from doing this?
We learned that Haskell is very modular, making it very easy to find versatile and diverse libraries that can increase both our efficiency and capabilities. The documentation available as part of hackage was also incredibly well written and easy to follow. Part of this has to do with Haskell's very explicit typing syntax, which allowed us to easily deduce how and where we ought to use what functions.
This project was very helpful in giving us a practical example of how to write code with constant IO interactions and several Maybe/Just/Nothing cases. One very interesting thing that we want to look into more is how continuous listeners work in functional programming languages, where one would expect the logic within the function ought to terminate at the end of the function.
Some examples of our learnings are listed below.
Haskell's haskell-gi library exists as a port of the GTK UI framework written in C. This allowed us to write a UI with a robust framework of standardized Unix-based elements that will run on any GTK-supporting Unix system. By using a glade xml file and a css file, we were able to declare GTK-defined objects that we could manipulate directly in Haskell code. Access to glade was particularly helpful because we were able to see an approximation of the final structure of our UIs in real time as we wrote them.
Haskell was very effective at allowing us to pass in basic matrix-algebraic functions for creating several unique convolutions. As well, the very same library included a vast series of built-in functions that included automatic image manipulations. Haskell allows for very fast and effective debugging with descriptive error messages, particularly for typing errors, and the occasional recommendation. That said, the error messages were a tad too verbose some of the time.
Stack and Cabal. There aren't very clear guidelines as to when to use Stack and when to use Cabal and then again when to use both. In our implementation, we used Stack to isolate an instance of GHC and all of the required libraries, but this seems like a very inefficient and tedious process for large projects. On one of our team-mates' computers, the initial build process took roughly half an hour, and took up several gigabytes of space. As well, it's not always clear which libraries are supported by which versions of GHC. We had to do a lot of trial and error in finding libraries that did what we wanted and were also compatible with the version of GHC that we decided to use.
Links to code etc:
git : https://github.com/masnax/all-the-functions
Instructions to create the environment and use the UI is specified in README.md