Age | Commit message (Collapse) | Author | Files | Lines |
|
Use Nix and Briefcase to easily create Haskell executables.
I'd eventually like to support something like: briefcase.buildHaskell.project
that let me define a few top-level values (e.g. ghcExtensions) and would give me
a ghci environment with the proper `.ghci` settings so that my development
environment mirrored my build environment... baby steps, though.
|
|
Small but useful alias.
|
|
Per the assignment's instructions, the `Shift n` operation should treat
the *entire keyboard* like a cycle and shift that. I was erroneously
treating *each row* like a cycle and shifting those one-by-one.
This change fixes that. In addition, it also:
- Updates README.md with expected inputs and outputs
- Updates test suite
- Adds `split` dependency to {default,shell}.nix
|
|
Tests:
- HorizontalFlip
- VerticalFlip
- Shift n
|
|
TL:DR:
- Remove unused imports: Test.QuickCheck and Control.Exception
- Remove calls to `reverse` and `Utils.rotate` with their results
|
|
TL;DR:
- include a default.nix to allow users to build an named executable
- emphasize in the README that the user needs Nix to build this project
- pin nixpkgs to a specific commit and fetch it from GitHub
|
|
Per my take-home assignment's reviewer's comments, with which for the record I
agree, I should generate the character->coordinate table from my existing qwerty
keyboard definition.
The best part is: by doing this I found a bug: Notice how the original '0'
character was mapped to the Coordinate (0,0)... thus every subsequent digit
key (i.e. the first row) is off-by-one.
|
|
After burning a few hours wrestling with the type system, I decided to revert to
the simpler `Server API` type instead of the `ServantT` transformer type.
The problem is that I couldn't write a MonadError instance for `RIO Context`,
which is my `AppM` (i.e. application monad). Using `throwIO` in the server
handlers results in 500 errors, which is not what I wanted. I'm still pretty
fuzzy about what's happening; I now know that exception handling in Haskell is
pretty gnaryly. I may revisit this at a later time when my knowledge is more
extensive. For now: time to fry bigger fish.
An easier abstract is for me to pass `T.Context` into `server` as an argument,
which after all is what a Reader does.
TL;DR:
- Read server, client ports from .envrc
- Define a top-level Failure type (empty for now)
- Define a top-level Success type
- Define App as RIO Context (Either Failure Success)
|
|
Long story -> short: I'd like to access my App monad from within my Servant
handlers.
While this code type-checks, I'm not sure it's working as intended. Needing to
change throwError to throwIO fails the "smell test". I expect to refactor this
code, but I'm calling it a night for now.
|
|
I believe RIO stands for: "ReaderT <something-something> IO", which is a nod to
the top-level application data type:
```haskell
-- This is a simplification
newtype RIO env a = RIO { runRIO :: ReaderT env a () }
```
I read about RIO from an FP-Complete blog post a few months ago, and now I'm
excited to try it out for a real project. Bon voyage!
|
|
I'm getting tired of:
```shell
$ cd <project-root>
$ nix-shell
$ cd src/server
$ ghci Main.hs
```
Instead:
```shell
$ cd <project-root>/src/server
$ ghci Main.hs
```
|
|
Defining a few tables in init.sql to sketch a few records that I need to
persist.
|
|
As the previous commit mentions, I'm attempting to build and deploy this project
with `nix-shell` and `nix-build` instead of `cabal` and `stack`.
I'm in the Hamburg airport right now, and my internet connection isn't stable
enough to test this, so I'm committing it until I can more robustly test it.
|
|
I'd like to see if I can avoid using `cabal` and `stack` and build and deploy
this application using `nix-shell` and `nix-build` only. Let's see how that
goes.
|
|
TL;DR:
- Consume GoogleSignIn.validateJWT in the Handler for /verify
- Rename validation fn to validateJWT
- Prefer Text to String type
|
|
Assert that the exp field of the JWT is "fresh".
|
|
The JWT should match "accounts.google.com" or "https://accounts.google.com". If
it doesn't, we produce a validation error.
TL;DR:
- Group all failed stringOrURI function calls as StringOrURIParseFailure errors
|
|
The subject of this commit message says it all.
|
|
Test that when the JWT contains the client ID for my Google app, the JWT is
valid, and when it doesn't, it's invalid.
|
|
I need IO for:
- Getting the current time to validate `exp`
- Making an HTTP request to Google's token verifier endpoint
|
|
Thank you, -Wall. You are truly an unsung hero.
|
|
I'm attempting to be an obedient boy and implement this and future features
using TDD.
TL;DR:
- Defined a few tests
- Defined an empty GoogleSignIn module
- Defined a Fixtures module to quickly create JWTs to test
|
|
Dumping grounds for personal, stylistic functions intended to improve readabily
and writability (in that order).
|
|
TL;DR:
- Add common dependencies like Servant, Aeson, Warp, Cors
- Define a POST /verify endpoint for our client to hit
- POST to /verify client-side onSignIn
|
|
TODO: Support Google Sign-in server-side
Also:
- Add Haskell to project's shell.nix
- Add stubbed Main.hs and Spec.hs
- Add common .ghci file
|
|
Remember: always read the instructions; that's the most important part.
|
|
Partially optimize inputs and document rules for further optimizations we can
make.
|
|
TL;DR:
- Accept input from the CLI
- Add a project README.md
|
|
Apply the transform to a Keyboard. Onwards to the final demonstration!
|
|
Using Haskell's Text.ParserCombinators.ReadP library for the first time, and I
enjoyed it thoroughly! It's nice avoiding a third-party library like MegaParsec.
|
|
This will help me debug.
|
|
To stylize things...
|
|
As I attempt to habituate TDD, I should have some examples of tests to minimize
all friction preventing me from testing.
|
|
After consuming my Elm boilerplate, I realized that I was missing this.
|
|
Before starting my take-home assignment, the instructions advised me to create a
"Hello, world" program in the language of my choice. Since I'm choosing Haskell,
I created this example as my starter boilerplate.
|
|
Many Bollywood movies have excellent acting, excellent directing, excellent
storytelling, but in my opinion, they spoil this with unnecessary musicals
interspersed throughout the films.
Dangal is a notable exception here. Overall, I'd say that this movie is
appropriately rated!
|
|
Watched the famous "Vertigo" with the timeless Jimmy Stewart. Overall I'd say
that the film is overhyped, but worth watching nevertheless.
|
|
I don't plan on writing movie reviews in my Git commit message.
|
|
Show the movies from directors that appear more than once in the list.
|
|
Defining some commonly used criteria for selecting movies as SQL queries.
|
|
What a confusing movie this was... I may need to watch it a second time to
better understand what happened, but I found watching it once already so
exhausting that I'm not sure I'll ever watch it again.
|
|
Added the following fields (would be cool if `git` could show this):
- rating
- haveWatched
- director
- isCartoon
- requiresSubtitles
|
|
Write a playbook for using SQLite to capture some trivia that I often forget in
between my ~infrequent uses of SQLite.
|
|
Taken from the overview:
> I'm making this as an offline reference for some of the commands that I use
> often enough to need to remember but not often enough to *actually* remember.
|
|
Prefer these more human-readable defaults to SQLite.
|
|
The astute observer may notice that the number of entries in db.sqlite3 is fewer
than the number of unwatched movies in imdb-top-250.org. I'm at a lake in
Germany with Mimi and Cullen, so we took the intersection of my unwatched
movies, Mimi's unwatched movies, and Cullen's unwatched movies.
|
|
I needed to add the first step since I dipped into my Emergency fund last month
to pay for someone to prepare my US tax return. I added the other step as a
reminder.
|
|
amount -> amounts
|
|
Back when I owned an iPhone -- before I switched (mistakenly and thus
temporarily) to Android -- I had a note for each year's newly learned words. As
I am condensing as many of my documents as possible into my briefcase, I decided
it is time for including a dictionary.
I can still record words on my phone, and then I can transfer them to this
document.
|
|
In the beginning there existed only a generic //org directory... This directory
was generic enough to include any .org file regardless of its purpose, but
specific enough to disallow membership of other worthy files of the Markdown
ilk.
Then came the //playbooks directory, which robbed //org of most of its
inhabitants...
In the interim various .md and .org TODO lists existed scattered across the
landscape of the monorepo... some existed in far-away, exotic lands like
"travel-histlist"... These fractious tribes shared much in common with their
distant relatives, but the superficial differences granted the simple-minded,
draconian filesystem license to prevent them from mingling.
Then one day the monorepo had a new visitor: //todo-lists.
//todo-lists restored order to the monorepo, uniting all of the fractious
documents under one roof.
.md and .org files held hands and sang Kumbaya around a blazing fire for the
first time in history. All was well, and all were happy.
|