Compare commits
35 Commits
configurin
...
master
Author | SHA1 | Date | |
---|---|---|---|
29deb31729 | |||
a1be811d95 | |||
bd41cf2f64 | |||
e48ec6ce3d | |||
b46cf0bf15 | |||
3bc2738ef6 | |||
69a1f4d921 | |||
a762b8b6fe | |||
394a511187 | |||
a19640ec02 | |||
c50529e44e | |||
fb9eea52a6 | |||
95e9b07f31 | |||
f8bd7e928d | |||
96f76a7751 | |||
a0640e1c0a | |||
8727fd33a6 | |||
869ad66b21 | |||
97afd713df | |||
a49af625bf | |||
7056ca822c | |||
7e290bee2f | |||
59cf230683 | |||
637fc7646b | |||
c62ff908af | |||
712b61059f | |||
2ead146d6a | |||
0ac70566cd | |||
809599d830 | |||
2e2f7b9be1 | |||
b0f0d15475 | |||
e951f7217f | |||
f7023b4431 | |||
08ad6fb469 | |||
b93aab5742 |
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
_site/
|
_site/
|
||||||
_cache/
|
_cache/
|
||||||
dist/
|
dist/
|
||||||
|
dist-newstyle/
|
||||||
|
result*
|
||||||
|
1
cabal.project
Normal file
@ -0,0 +1 @@
|
|||||||
|
packages: */*.cabal
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
title: Contact
|
|
||||||
---
|
|
||||||
|
|
||||||
I live in Espoo Finland. You can contact me on any of the following services.
|
|
||||||
|
|
||||||
- **Email**: mats@rauhala.info
|
|
||||||
- **Slack**: masser@functionalprogramming.slack.com
|
|
||||||
- **IRC**: MasseR@freenode
|
|
||||||
- **Mastodon**: MasseR@mastodon.social
|
|
@ -1,3 +1,8 @@
|
|||||||
{ haskellPackages, haskell }:
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
|
||||||
haskell.lib.disableSharedExecutables (haskellPackages.callCabal2nix "site" ./. {})
|
with pkgs;
|
||||||
|
|
||||||
|
rec {
|
||||||
|
site = haskellPackages.callPackage ./site {};
|
||||||
|
rauhala-info = callPackage ./rauhala.info { site = site; };
|
||||||
|
}
|
||||||
|
43
flake.lock
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1659877975,
|
||||||
|
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1660646295,
|
||||||
|
"narHash": "sha256-V4G+egGRc3elXPTr7QLJ7r7yrYed0areIKDiIAlMLC8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "762b003329510ea855b4097a37511eb19c7077f0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
37
flake.nix
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
description = "rauhala.info";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
{
|
||||||
|
}
|
||||||
|
//
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
hp = pkgs.haskellPackages.override ( old: {
|
||||||
|
overrides = pkgs.lib.composeExtensions ( old.overrides or (_: _: {})) (f: p: {
|
||||||
|
build-rauhala-info = f.callPackage ./site {};
|
||||||
|
});
|
||||||
|
} );
|
||||||
|
in
|
||||||
|
rec {
|
||||||
|
packages.rauhala-info = pkgs.callPackage ./rauhala.info { site = hp.build-rauhala-info; };
|
||||||
|
defaultPackage = packages.rauhala-info;
|
||||||
|
devShell = hp.shellFor {
|
||||||
|
packages = h: [h.build-rauhala-info];
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
ghcid
|
||||||
|
cabal-install
|
||||||
|
stylish-haskell
|
||||||
|
entr
|
||||||
|
haskell-language-server
|
||||||
|
ipfs
|
||||||
|
];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
Before Width: | Height: | Size: 10 KiB |
@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
title: Mats Rauhala
|
|
||||||
---
|
|
||||||
|
|
||||||
![](./images/profile.jpg)
|
|
||||||
|
|
||||||
I'm a software developer from southern Finland. I'm currently working as a
|
|
||||||
Haskell developer at Relex Oy involved in an internal tool. I also have
|
|
||||||
experience with systems integrations and backend web development.
|
|
||||||
|
|
||||||
I'm also an aviation enthusiast. I have a glider pilots license and a touring
|
|
||||||
motor glider pilots license (LAPL(S)+TMG).
|
|
||||||
|
|
||||||
My [GPG key](./resources/2104943D6033C.txt)
|
|
||||||
|
|
||||||
### Notable experience and interests
|
|
||||||
|
|
||||||
- **Haskell**
|
|
||||||
- Working on an internal Haskell based tool at Relex Oy
|
|
||||||
- Some contributions to [darcshub](https://hub.darcs.net/)
|
|
||||||
- Some contributions to [xmonad](https://github.com/xmonad)
|
|
||||||
- Dozens of personal projects, most of which ended up being just tests for
|
|
||||||
different libraries, techniques or algorithms.
|
|
||||||
- **Systems integrations**
|
|
||||||
- Working as a consultant from Avoltus Oy to different companies using
|
|
||||||
[Mulesoft](https://developer.mulesoft.com/). Systems include webshops,
|
|
||||||
different databases, CRMs and ERPs.
|
|
||||||
- **Java**
|
|
||||||
- Bunch of different smaller projects while working at Avoltus Oy.
|
|
||||||
- **Other**
|
|
||||||
- I was involved in creating an email solicit platform.
|
|
22
js/api.js
@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
var getApiIpfsCurrent = function(onSuccess, onError) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.open('GET', '/api/ipfs/current', true);
|
|
||||||
xhr.setRequestHeader('Accept', 'application/json');
|
|
||||||
xhr.onreadystatechange = function () {
|
|
||||||
var res = null;
|
|
||||||
if (xhr.readyState === 4) {
|
|
||||||
if (xhr.status === 204 || xhr.status === 205) {
|
|
||||||
onSuccess();
|
|
||||||
} else if (xhr.status >= 200 && xhr.status < 300) {
|
|
||||||
try { res = JSON.parse(xhr.responseText); } catch (e) { onError(e); }
|
|
||||||
if (res) onSuccess(res);
|
|
||||||
} else {
|
|
||||||
try { res = JSON.parse(xhr.responseText); } catch (e) { onError(e); }
|
|
||||||
if (res) onError(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.send(null);
|
|
||||||
};
|
|
||||||
|
|
10
js/app.js
@ -1,10 +0,0 @@
|
|||||||
$(document).ready(function() {
|
|
||||||
var success = function(x) {
|
|
||||||
$("#ipfs > em").html(x);
|
|
||||||
};
|
|
||||||
var error = function(x) {
|
|
||||||
$("#ipfs").hide();
|
|
||||||
console.log("ipfs hash not found: " + x);
|
|
||||||
};
|
|
||||||
getApiIpfsCurrent(success, error);
|
|
||||||
});
|
|
2
js/jquery-3.3.1.min.js
vendored
7
nixpkgs.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"url": "https://github.com/NixOS/nixpkgs",
|
||||||
|
"rev": "7e1f60dfbba67b975d1a77d710a6f1437fd9709c",
|
||||||
|
"date": "2020-02-01T09:20:37-05:00",
|
||||||
|
"sha256": "0vk55459iljr5dzwnr5661l44b0wdc15952lk2rjcmxr1620yr5v",
|
||||||
|
"fetchSubmodules": false
|
||||||
|
}
|
@ -1,78 +0,0 @@
|
|||||||
---
|
|
||||||
title: Extensible configuration Pt. 1
|
|
||||||
date: 2019-03-27
|
|
||||||
---
|
|
||||||
|
|
||||||
This is the first part of a series where I'm going through how to make
|
|
||||||
extensible configuration. There is nothing groundbreaking or new in this
|
|
||||||
series, it's just me going through different implementations and trying to
|
|
||||||
understand them.
|
|
||||||
|
|
||||||
The source material for this post is [the fixed point implementation](https://github.com/NixOS/nixpkgs/blob/master/lib/fixed-points.nix) for nix.
|
|
||||||
|
|
||||||
By extensible configuration, I'm talking about nix style extensible
|
|
||||||
configuration, like overlays, overrides and extensions. Let's see an example of
|
|
||||||
an extensible configuration.
|
|
||||||
|
|
||||||
``` nix
|
|
||||||
{ haskellPackages, fetchFromGitHub }:
|
|
||||||
|
|
||||||
let
|
|
||||||
purescript = fetchFromGitHub {
|
|
||||||
owner = "purescript";
|
|
||||||
repo = "purescript";
|
|
||||||
rev = "2cb4a6496052db726e099539be682b87585af494";
|
|
||||||
sha256 = "1v4gs08xnqgym6jj3drkzbic7ln3hfmflpbpij3qzwxsmqd2abr7";
|
|
||||||
}
|
|
||||||
hp = haskellPackages.extend (self: super: {
|
|
||||||
purescript = super.callCabal2nix "purescript" purescript {};
|
|
||||||
});
|
|
||||||
|
|
||||||
in
|
|
||||||
|
|
||||||
hp.purescript;
|
|
||||||
```
|
|
||||||
|
|
||||||
On a high level we are augmenting the `haskellPackages` attrset by replacing
|
|
||||||
the existing purescript package with a different one. The extension is a
|
|
||||||
function that takes two arguments, `self` and `super`. `super` is the original
|
|
||||||
non-lazy value and `self` is the lazy value that corresponds to the value at
|
|
||||||
end.
|
|
||||||
|
|
||||||
The first step on this journey is done by getting to know `fix`. Fix is
|
|
||||||
described being the least fixed point of a function. In practice it's a
|
|
||||||
function allowing declaring recursive functions without explicit recursion.
|
|
||||||
|
|
||||||
``` nix
|
|
||||||
fix = f: let x = f x; in x
|
|
||||||
```
|
|
||||||
|
|
||||||
With fix you can have access to the lazy `self` value. It's value is whatever
|
|
||||||
would have been computed in the end. As it is lazy, it is possible to end up in
|
|
||||||
a recursive loop if there is a cyclic dependency.
|
|
||||||
|
|
||||||
``` nix
|
|
||||||
let recursive = fix (self: {
|
|
||||||
foo = 3;
|
|
||||||
bar = self.foo + 1;
|
|
||||||
});
|
|
||||||
infinite = fix (self: {
|
|
||||||
foo = self.bar + 1;
|
|
||||||
bar = self.foo + 1;
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
You can try those yourself. The first version is fine and returns an attrset
|
|
||||||
like you would expect. The second one has a cyclic dependency and nix helpfully
|
|
||||||
errors out.
|
|
||||||
|
|
||||||
The next step is making a function that has access to the unmodified original
|
|
||||||
values. This is managed through the `extends` function. It took a while for me to understand what's happening in there, but luckily nix has [good documentation](https://github.com/NixOS/nixpkgs/blob/67b1265fb3d38ead5a57fee838405a2d997777c2/lib/fixed-points.nix#L37-L65) for it.
|
|
||||||
|
|
||||||
``` nix
|
|
||||||
extends = f: rattrs: self: let super = rattrs self; in super // f self super
|
|
||||||
```
|
|
||||||
|
|
||||||
- https://elvishjerricco.github.io/2017/04/01/nix-style-configs-in-haskell.html
|
|
||||||
- https://github.com/NixOS/nixpkgs/blob/master/lib/fixed-points.nix
|
|
||||||
- https://chshersh.github.io/posts/2019-03-25-comonadic-builders
|
|
148
posts/demobot.md
@ -1,148 +0,0 @@
|
|||||||
---
|
|
||||||
title: Functional architecture Pt. 1
|
|
||||||
date: 2018-12-25
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
I'm lucky enough to work with Haskell professionally which gives me some view
|
|
||||||
to good and maintainable real world architecture. In my opinion, one of the
|
|
||||||
biggest contributing factors to how your general architecture is defined, is
|
|
||||||
determined by the base application monad stack you are using.
|
|
||||||
|
|
||||||
Our actual product is mostly in the regular `LoggingT (ReaderT app IO)` base
|
|
||||||
monad with whatever style you would imagine with that base monad in place. It's
|
|
||||||
not entirely consistent, but close enough.
|
|
||||||
|
|
||||||
With all the talk about just having `IO`, `ReaderT app IO`, free monads or
|
|
||||||
tagless final monads, I thought of trying different styles. For this post I'm
|
|
||||||
focusing on the tagless final since it's most interesting for me right now.
|
|
||||||
|
|
||||||
`IO`
|
|
||||||
|
|
||||||
: The most basic style. This is pretty much only suitable for the most basic
|
|
||||||
of needs.
|
|
||||||
|
|
||||||
`ReaderT app IO`
|
|
||||||
|
|
||||||
: How we mostly define the base monad. This is a really good way of doing
|
|
||||||
things, it gives you a lot of leeway on how you can define the rest of your
|
|
||||||
application.
|
|
||||||
|
|
||||||
`Free monads`
|
|
||||||
|
|
||||||
: Free monads are a way of having a small constrained DSL or monad stack for
|
|
||||||
defining your application. By constraining the user, you are also reducing the
|
|
||||||
area for bugs. There is also some possibility for introspection, but usually
|
|
||||||
this isn't a usable feature. Also since free monad applications need the full
|
|
||||||
AST, they're quite a bit slower than the other solutions.
|
|
||||||
|
|
||||||
`Tagless final`
|
|
||||||
|
|
||||||
: This is something I'm the least familiar with. If I have understood
|
|
||||||
correctly, free monads and tagless final are more or less equivalent solutions
|
|
||||||
in their power, but in tagless final you aren't creating the AST anywhere,
|
|
||||||
which also means that you aren't paying for it either.
|
|
||||||
|
|
||||||
That out of the way, I had a small project idea for a bot that's easy to
|
|
||||||
contribute to, difficult to make errors and easy to reason about. The project
|
|
||||||
is at most a proof-of-concept and most definitely not production quality.
|
|
||||||
Still, I hope it's complex enough to showcase the architecture.
|
|
||||||
|
|
||||||
The full source code is available [at my git repository](https://git.rauhala.info/MasseR/demobot).
|
|
||||||
|
|
||||||
For the architecture to make sense, let me introduce two different actors: a
|
|
||||||
*core contributor* that's familiar with Haskell and a *external contributor*
|
|
||||||
that's familiar with programming, not necessarily with Haskell.
|
|
||||||
|
|
||||||
The repository is split into two parts, the library and the application.
|
|
||||||
|
|
||||||
The library
|
|
||||||
|
|
||||||
: Provides the restricted monad classes (tagless final), extension points and
|
|
||||||
the core bot main loop.
|
|
||||||
|
|
||||||
The application
|
|
||||||
|
|
||||||
: Provides the implementation for the tagless final type classes, meaning
|
|
||||||
that the application defines how the networking stack is handled, how database
|
|
||||||
connectivity is done and so on. It also collects all the extensions for that
|
|
||||||
specific application.
|
|
||||||
|
|
||||||
The *core contributor* is responsible for maintaining the library as well as
|
|
||||||
the type class instances for the application type. The *external contributor*
|
|
||||||
is responsible for maintaining one or multiple extensions that are restricted
|
|
||||||
in their capability and complexity.
|
|
||||||
|
|
||||||
I'm restricting the capabilities of the monad in the library and extensions,
|
|
||||||
meaning that I'm not allowing any IO. For example the networking is handled by
|
|
||||||
a single `MonadNetwork` type class. This is the most complex type class in the
|
|
||||||
library right now, using type families for defining a specific extension point
|
|
||||||
for the messages. This could be something like 'event type' for Flowdock
|
|
||||||
messages or 'source channel' for IRC messages.
|
|
||||||
|
|
||||||
~~~haskell
|
|
||||||
data Request meta = Request { content :: Text
|
|
||||||
, meta :: meta }
|
|
||||||
data Response meta = Response { content :: Text
|
|
||||||
, meta :: meta }
|
|
||||||
|
|
||||||
class Monad m => MonadNetwork m where
|
|
||||||
type Meta m :: *
|
|
||||||
recvMsg :: m (Request (Meta m))
|
|
||||||
putMsg :: Response (Meta m) -> m ()
|
|
||||||
~~~
|
|
||||||
|
|
||||||
Then we have the extension point which is more or less just a `Request -> m (Maybe Response)`. I'm using rank n types here for qualifying the `Meta`
|
|
||||||
extension point and forcing the allowed type classes to be a subset of the
|
|
||||||
application monad stack, I don't want extension writers to be able to write
|
|
||||||
messages to the bot network by themselves.
|
|
||||||
|
|
||||||
~~~haskell
|
|
||||||
data Extension meta =
|
|
||||||
Extension { act :: forall m. (meta ~ Meta m, MonadExtension m) => Request meta -> m (Maybe (Response meta))
|
|
||||||
, name :: String }
|
|
||||||
~~~
|
|
||||||
|
|
||||||
Last part of the library is the main loop, which is basically a free monad
|
|
||||||
(tagless final) waiting for an interpreter. At least in this POC I find this
|
|
||||||
style to be really good, it's really simplified, easy to read and hides a lot
|
|
||||||
of the complexity, while bringing forth the core algorithm.
|
|
||||||
|
|
||||||
~~~haskell
|
|
||||||
mainLoop :: forall m. (MonadCatch m, MonadBot m) => [Extension (Meta m)] -> m ()
|
|
||||||
mainLoop extensions = forever $ catch go handleFail
|
|
||||||
where
|
|
||||||
handleFail :: SomeException -> m ()
|
|
||||||
handleFail e = logError $ tshow e
|
|
||||||
go :: m ()
|
|
||||||
go = do
|
|
||||||
msg <- recvMsg
|
|
||||||
responses <- catMaybes <$> mapM (`act` msg) extensions
|
|
||||||
mapM_ putMsg responses
|
|
||||||
~~~
|
|
||||||
|
|
||||||
Then comes the actual application where we write the effectful interpreters. In
|
|
||||||
this POC the interpreter is just a `LoggingT IO a` with the semantics of
|
|
||||||
stdin/stdout. This is the only file where we're actually interacting with the
|
|
||||||
outside world, everything else is just pure code.
|
|
||||||
|
|
||||||
~~~haskell
|
|
||||||
instance MonadNetwork AppM where
|
|
||||||
type Meta AppM = ()
|
|
||||||
recvMsg = Request <$> liftIO T.getLine <*> pure ()
|
|
||||||
putMsg Response{..} = liftIO . T.putStrLn $ content
|
|
||||||
~~~
|
|
||||||
|
|
||||||
Writing the extensions was the responsibility of *external contributors* and we
|
|
||||||
already saw how the actual extension point was defined above. Using these
|
|
||||||
extension points is really simple and here we see how the implementation is
|
|
||||||
just a simple `Request -> m (Maybe Response)`.
|
|
||||||
|
|
||||||
~~~haskell
|
|
||||||
extension :: Extension ()
|
|
||||||
extension = Extension{..}
|
|
||||||
where
|
|
||||||
name = "hello world"
|
|
||||||
act Request{..} | "hello" `T.isPrefixOf` content = return $ Just $ Response "Hello to you" ()
|
|
||||||
| otherwise = return Nothing
|
|
||||||
~~~
|
|
2
rauhala.info/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
_site
|
||||||
|
_cache
|
8
rauhala.info/contact.markdown
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: Contact
|
||||||
|
---
|
||||||
|
|
||||||
|
I live in Espoo Finland. You can contact me on any of the following services.
|
||||||
|
|
||||||
|
- **Email**: mats.rauhala@iki.fi
|
||||||
|
- **Mastodon**: MasseR@haskell.social
|
@ -39,6 +39,18 @@ h2 {
|
|||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.projectlist {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
article.blog {
|
||||||
|
/* display: flex; */
|
||||||
|
/* align-items: center; */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
article .header {
|
article .header {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
@ -51,6 +63,7 @@ article .header {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 319px) {
|
@media (max-width: 319px) {
|
||||||
body {
|
body {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
@ -107,14 +120,40 @@ article .header {
|
|||||||
display: inline;
|
display: inline;
|
||||||
margin: 0 0.6rem;
|
margin: 0 0.6rem;
|
||||||
}
|
}
|
||||||
|
div.sidebar-container {
|
||||||
|
/* display: grid; */
|
||||||
|
/* grid-template-columns: minmax(60%, 85%) 1fr; */
|
||||||
|
}
|
||||||
|
div.sidebar-container > div.sidebar {
|
||||||
|
padding-top: 2rem;
|
||||||
|
border-top: 0.2rem solid #000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
body {
|
body {
|
||||||
width: 85rem;
|
width: 100rem;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
div.sidebar-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(60%, 85%) 1fr;
|
||||||
|
}
|
||||||
|
div.sidebar-container > div.sidebar {
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-left: 2rem;
|
||||||
|
border-left: 0.2rem solid #000;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
article {
|
||||||
|
width: 60rem;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
header {
|
header {
|
||||||
margin: 0 0 3rem;
|
margin: 0 0 3rem;
|
||||||
padding: 1.2rem 0;
|
padding: 1.2rem 0;
|
@ -1,18 +1,6 @@
|
|||||||
/* Generated by pandoc. */
|
/* Generated by pandoc. */
|
||||||
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre.sourceCode
|
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre
|
||||||
{
|
{ margin: 0; padding: 0; border: 0; vertical-align: baseline; border: none; }
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
/* border: 0; */
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
pre.sourceCode
|
|
||||||
{
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
background-color: rgb(238,238,255);
|
|
||||||
padding: 10px;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; }
|
td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; }
|
||||||
td.sourceCode { padding-left: 5px; }
|
td.sourceCode { padding-left: 5px; }
|
||||||
.sourceCode span.kw { color: #007020; font-weight: bold; }
|
.sourceCode span.kw { color: #007020; font-weight: bold; }
|
24
rauhala.info/default.nix
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{ stdenv, glibcLocales, site }:
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "rauhala.info";
|
||||||
|
version = "0.1.0";
|
||||||
|
|
||||||
|
src = builtins.filterSource (path: type: baseNameOf path != "_cache" && baseNameOf path != "_site") ./.;
|
||||||
|
|
||||||
|
phases = ["buildPhase" "installPhase"];
|
||||||
|
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
export LOCALE_ARCHIVE="${glibcLocales}/lib/locale/locale-archive"
|
||||||
|
export LANG=en_US.UTF-8
|
||||||
|
|
||||||
|
cp -r $src/* .
|
||||||
|
${site}/bin/site build
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/share/
|
||||||
|
cp -r _site/* $out/share/
|
||||||
|
'';
|
||||||
|
}
|
Before Width: | Height: | Size: 684 B After Width: | Height: | Size: 684 B |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 485 B After Width: | Height: | Size: 485 B |
Before Width: | Height: | Size: 684 B After Width: | Height: | Size: 684 B |
BIN
rauhala.info/images/profile.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
32
rauhala.info/index.markdown
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
title: Mats Rauhala
|
||||||
|
---
|
||||||
|
|
||||||
|
![](./images/profile.jpg)
|
||||||
|
|
||||||
|
I'm a software developer from southern Finland. I'm currently working as a
|
||||||
|
Haskell developer at Relex Oy. I also have experience with systems integrations
|
||||||
|
and backend web development.
|
||||||
|
|
||||||
|
My [GPG key](./resources/0x9DE6E04ED1918118.txt)
|
||||||
|
|
||||||
|
### Notable experience and interests
|
||||||
|
|
||||||
|
- **Relex Oy**
|
||||||
|
- Working as a Lead Software Developer at Relex Oy
|
||||||
|
- Transitioned from day to day code to a role more close to an architect
|
||||||
|
- Three distinct products, all of which written in Haskell
|
||||||
|
- Internal integration tool
|
||||||
|
- Relex Deploy 1, a tool for deploying the core product to hosts
|
||||||
|
- Relex Deploy 2, a tool for deploying the new and shiny core product to hosts
|
||||||
|
- **Open source**
|
||||||
|
- Some contributions to [darcshub](https://hub.darcs.net/)
|
||||||
|
- Some contributions to [xmonad](https://github.com/xmonad)
|
||||||
|
- **Systems integrations**
|
||||||
|
- Working as a consultant from Avoltus Oy to different companies using
|
||||||
|
[Mulesoft](https://developer.mulesoft.com/). Systems include webshops,
|
||||||
|
different databases, CRMs and ERPs.
|
||||||
|
- **Java**
|
||||||
|
- Bunch of different smaller projects while working at Avoltus Oy.
|
||||||
|
- **Other**
|
||||||
|
- I was involved in creating an email advertising platform.
|
254
rauhala.info/posts/2021-01-26-Tests-with-Deriving.md
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
---
|
||||||
|
title: Tests with Deriving Via
|
||||||
|
tags: haskell, testing, pbt
|
||||||
|
---
|
||||||
|
|
||||||
|
I have been using both `hedgehog` and `QuickCheck` based property-based testing
|
||||||
|
frameworks, I'm fairly comfortable in writing tests and generators in both.
|
||||||
|
Theoretical aspects aside, for a user, I feel like `hedgehog` is more
|
||||||
|
ergonomic as it does automatic shrinking *and* does away with typeclasses. The
|
||||||
|
former is important as writing good shrinkers is hard, remembering to write
|
||||||
|
shrinkers is even harder. The latter is important when you need to modify your
|
||||||
|
generation for some tests.
|
||||||
|
|
||||||
|
In this post, I'll show that using `DerivingVia` extension and generic
|
||||||
|
coercions can help you write almost as ergonomic `Arbitrary` definitions for
|
||||||
|
`QuickCheck`. The initial idea is taken from the
|
||||||
|
[Deriving Via](https://www.kosmikus.org/DerivingVia/deriving-via-paper.pdf) paper,
|
||||||
|
but taken a little bit further. This post assumes some level of understanding
|
||||||
|
of type level programming.
|
||||||
|
|
||||||
|
For the examples, we're using a `Person` as shown in the examples below. The
|
||||||
|
test we'll implement will be the `tripping` property. For the *expected*
|
||||||
|
values, the `name` is something name-like and `age` is a range between 1-99.
|
||||||
|
|
||||||
|
I'll use `hedgehog` to write the ideal case. The generator is light-weight, but
|
||||||
|
has been customized for the business case. I'm using the `hedgehog-corpus`
|
||||||
|
package for the name-like generation.
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
import GHC.Generics (Generic)
|
||||||
|
|
||||||
|
import Data.Text (Text)
|
||||||
|
|
||||||
|
import qualified Data.Aeson as A
|
||||||
|
|
||||||
|
import Hedgehog
|
||||||
|
import qualified Hedgehog.Gen as Gen
|
||||||
|
import qualified Hedgehog.Range as Range
|
||||||
|
import qualified Hedgehog.Corpus as Corpus
|
||||||
|
|
||||||
|
data Person
|
||||||
|
= Person { name :: Text
|
||||||
|
, age :: Int
|
||||||
|
}
|
||||||
|
deriving stock (Show, Eq, Generic)
|
||||||
|
deriving anyclass (A.ToJSON, A.FromJSON)
|
||||||
|
|
||||||
|
genValidPerson :: Gen Person
|
||||||
|
genValidPerson =
|
||||||
|
Person <$> Gen.element Corpus.simpsons
|
||||||
|
<*> Gen.integral (Range.linear 0 99)
|
||||||
|
|
||||||
|
prop_encoding :: Property
|
||||||
|
prop_encoding = property $ do
|
||||||
|
p <- forAll genValidPerson
|
||||||
|
pure p === A.eitherDecode (A.encode p)
|
||||||
|
```
|
||||||
|
|
||||||
|
For comparison, this is what I would write with QuickCheck without any helpers.
|
||||||
|
There's quite a bit of added complexity, especially in the shrinker, and only
|
||||||
|
with two fields.
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
import GHC.Generics (Generic)
|
||||||
|
|
||||||
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Aeson as A
|
||||||
|
|
||||||
|
import Test.QuickCheck
|
||||||
|
|
||||||
|
data Person
|
||||||
|
= Person { name :: Text
|
||||||
|
, age :: Int
|
||||||
|
}
|
||||||
|
deriving stock (Show, Eq, Generic)
|
||||||
|
deriving anyclass (A.ToJSON, A.FromJSON)
|
||||||
|
|
||||||
|
instance Arbitrary Person where
|
||||||
|
arbitrary = Person <$> elements simpsons <*> choose (1,99)
|
||||||
|
where
|
||||||
|
simpsons = ["bart", "marge", "homer", "lisa", "ned"]
|
||||||
|
shrink Person{name,age} =
|
||||||
|
[Person name' age'
|
||||||
|
| name' <- [name]
|
||||||
|
, age' <- shrinkIntegral age
|
||||||
|
, age' >= 1
|
||||||
|
, age' <= 99
|
||||||
|
]
|
||||||
|
|
||||||
|
prop_encoding :: Person -> Property
|
||||||
|
prop_encoding p = pure p === A.eitherDecode (A.encode p)
|
||||||
|
```
|
||||||
|
|
||||||
|
Good, now that the base is done, let's see what we can do about making
|
||||||
|
`QuickCheck` more ergonomic. The solution I'm outlining here relies on these
|
||||||
|
features.
|
||||||
|
|
||||||
|
- `DerivingVia` extension which can automatically generate instances for you if two types are `Coercible`
|
||||||
|
- Isomorphism between the `Generic` representation of two types. For example `(a,b)` has a `Generic` representation that is the same as `data Foo = Foo a b`
|
||||||
|
- `QuickCheck` modifiers, for example `PrintableString` which modify the arbitrary generation
|
||||||
|
|
||||||
|
The paper defines this piece of code for deriving `Arbitrary` instances for
|
||||||
|
anything that is generically isomorphic to something that is already an
|
||||||
|
instance.
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
newtype SameRepAs a b = SameRepAs a
|
||||||
|
|
||||||
|
instance
|
||||||
|
( Generic a
|
||||||
|
, Generic b
|
||||||
|
, Arbitrary b
|
||||||
|
, Coercible (Rep a ()) (Rep b ())
|
||||||
|
)
|
||||||
|
=> Arbitrary (a `SameRepAs` b) where
|
||||||
|
arbitrary = SameRepAs . coerceViaRep <$> arbitrary
|
||||||
|
where
|
||||||
|
coerceViaRep :: b -> a
|
||||||
|
coerceViaRep =
|
||||||
|
to . (coerce :: Rep b () -> Rep a ()) . from
|
||||||
|
```
|
||||||
|
|
||||||
|
For my implementation, I'll be cleaning the code from the paper. I'm swapping
|
||||||
|
the type parameters of the newtype and extract the coercion function to
|
||||||
|
top-level so that I can define the `shrink` as well.
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
newtype Isomorphic a b = Isomorphic b
|
||||||
|
|
||||||
|
type GenericCoercible a b =
|
||||||
|
( Generic a
|
||||||
|
, Generic b
|
||||||
|
, Coercible (Rep a ()) (Rep b ())
|
||||||
|
)
|
||||||
|
|
||||||
|
genericCoerce :: forall a b. GenericCoercible a b => a -> b
|
||||||
|
genericCoerce =
|
||||||
|
to . (coerce @(Rep a ()) @(Rep b ())) . from
|
||||||
|
|
||||||
|
instance
|
||||||
|
( Arbitrary a
|
||||||
|
, GenericCoercible a b
|
||||||
|
)
|
||||||
|
=> Arbitrary (a `Isomorphic` b) where
|
||||||
|
arbitrary = Isomorphic . genericCoerce @a @b <$> arbitrary
|
||||||
|
shrink (Isomorphic b) =
|
||||||
|
Isomorphic . genericCoerce @a @b
|
||||||
|
<$> shrink (genericCoerce @b @a b)
|
||||||
|
```
|
||||||
|
|
||||||
|
With this, we can now write `Arbitrary` instances using the tuple
|
||||||
|
representation as an intermediary. At least as long as the child types have
|
||||||
|
their instances properly set.
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
data Person
|
||||||
|
= Person { name :: Text
|
||||||
|
, age :: Int
|
||||||
|
}
|
||||||
|
deriving stock (Show, Eq, Generic)
|
||||||
|
deriving anyclass (A.ToJSON, A.FromJSON)
|
||||||
|
deriving (Arbitrary) via ((Text, Int) `Isomorphic` Person)
|
||||||
|
```
|
||||||
|
|
||||||
|
This is already a marked improvement to the original `Arbitrary` instance we
|
||||||
|
wrote, but this does not yet satisfy our original requirement of generating
|
||||||
|
only 'valid' persons. I would like to modify the instance generation on a more
|
||||||
|
ad-hoc fashion. For this to happen, I would need some *modifiers* that control
|
||||||
|
the arbitrary generation. I would like to write something like the instance
|
||||||
|
below.
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
type Simpsons = '["marge", "bart", "homer", "lisa", "ned"]
|
||||||
|
data Person
|
||||||
|
= Person { name :: Text
|
||||||
|
, age :: Int
|
||||||
|
}
|
||||||
|
deriving stock (Show, Eq, Generic)
|
||||||
|
deriving anyclass (A.ToJSON, A.FromJSON)
|
||||||
|
deriving (Arbitrary)
|
||||||
|
via ((Corpus Simpsons Text, Range 1 99 Int) `Isomorphic` Person)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Let's start by defining the `Range` as it's more straightforward. This is just
|
||||||
|
a `newtype` with a couple of phantom type variables, which is used in choosing
|
||||||
|
the range of the generator. Shrinking is already quite complex (and probably
|
||||||
|
not optimal!), I wouldn't want to write this multiple times.
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
newtype Range (from :: Nat) (to :: Nat) a = Range a
|
||||||
|
|
||||||
|
instance
|
||||||
|
( KnownNat from
|
||||||
|
, KnownNat to
|
||||||
|
, Num a
|
||||||
|
, Ord a
|
||||||
|
, Integral a
|
||||||
|
) => Arbitrary (Range from to a) where
|
||||||
|
arbitrary = Range . fromInteger <$> choose (natVal $ Proxy @from, natVal $ Proxy @to)
|
||||||
|
shrink (Range x) = Range <$> shrunk
|
||||||
|
where
|
||||||
|
shrunk =
|
||||||
|
[ x'
|
||||||
|
| x' <- shrinkIntegral x
|
||||||
|
, x >= fromInteger (natVal $ Proxy @from)
|
||||||
|
, x <= fromInteger (natVal $ Proxy @to)
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Then the corpus. Just like the `Range` it's a `newtype` with a phantom
|
||||||
|
variable, providing the input for the random generation. There's an extra
|
||||||
|
typeclass involved to act as a typelevel function.
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
newtype Corpus (corpus :: [Symbol]) a = Corpus a
|
||||||
|
|
||||||
|
class FromCorpus (corpus :: [Symbol]) where
|
||||||
|
fromCorpus :: [String]
|
||||||
|
|
||||||
|
instance FromCorpus '[] where
|
||||||
|
fromCorpus = []
|
||||||
|
|
||||||
|
instance (KnownSymbol x, FromCorpus xs) => FromCorpus (x ': xs) where
|
||||||
|
fromCorpus = symbolVal (Proxy @x) : fromCorpus @xs
|
||||||
|
|
||||||
|
instance (FromCorpus corpus, IsString x) => Arbitrary (Corpus corpus x) where
|
||||||
|
arbitrary = Corpus . fromString <$> elements (fromCorpus @corpus)
|
||||||
|
```
|
||||||
|
|
||||||
|
With these instances out of the way, we can redo our original test with
|
||||||
|
automatic instances.
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
import GHC.Generics (Generic)
|
||||||
|
|
||||||
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Aeson as A
|
||||||
|
|
||||||
|
import Test.QuickCheck
|
||||||
|
|
||||||
|
import Isomorphic
|
||||||
|
|
||||||
|
data Person
|
||||||
|
= Person { name :: Text
|
||||||
|
, age :: Int
|
||||||
|
}
|
||||||
|
deriving stock (Show, Eq, Generic)
|
||||||
|
deriving anyclass (A.ToJSON, A.FromJSON)
|
||||||
|
deriving Arbitrary via ((Corpus Simpsons Text, Range 1 99 Int) `Isomorphic` Person)
|
||||||
|
|
||||||
|
prop_encoding :: Person -> Property
|
||||||
|
prop_encoding p = pure p === A.eitherDecode (A.encode p)
|
||||||
|
```
|
37
rauhala.info/projects/2021-01-21-bidirectional.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
title: bidirectional
|
||||||
|
github: https://github.com/MasseR/bidirectional
|
||||||
|
issues: https://github.com/MasseR/bidirectional/issues
|
||||||
|
badge: https://github.com/MasseR/bidirectional/workflows/Test/badge.svg
|
||||||
|
---
|
||||||
|
|
||||||
|
Bidirectional serialization based on Lysxia's post on [Monadic profunctors for bidirectional programming](https://blog.poisson.chat/posts/2017-01-01-monadic-profunctors.html).
|
||||||
|
|
||||||
|
|
||||||
|
Let's assume we have a parser like the following
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
int :: Parser (ReaderT String Maybe) (Writer [Int]) Int Int
|
||||||
|
int = parser (ReaderT readMaybe) (\x -> x <$ tell [show x])
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can use the parser for parsing:
|
||||||
|
|
||||||
|
```
|
||||||
|
> runReaderT (decode int) "3"
|
||||||
|
Just 3
|
||||||
|
```
|
||||||
|
|
||||||
|
Or for encoding:
|
||||||
|
|
||||||
|
```
|
||||||
|
> execWriter (encode int 3)
|
||||||
|
["3"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Or combine both of them
|
||||||
|
|
||||||
|
```
|
||||||
|
> runReaderT (decode int) $ head $ execWriter $ encode int 3
|
||||||
|
Just 3
|
||||||
|
```
|
23
rauhala.info/projects/2021-01-21-phrase.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
title: phrase
|
||||||
|
github: https://github.com/MasseR/phrase
|
||||||
|
issues: https://github.com/MasseR/phrase/issues
|
||||||
|
badge: https://github.com/MasseR/phrase/workflows/Run nix build/badge.svg
|
||||||
|
---
|
||||||
|
|
||||||
|
This project is a command line tool for generating password phrases using the
|
||||||
|
[diceware method](https://diceware.dmuth.org/). The passwords are stored in a
|
||||||
|
folder structure that is compatible with the
|
||||||
|
[pass](https://www.passwordstore.org/) password store manager.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
$ phrase asd
|
||||||
|
inlet area crux
|
||||||
|
|
||||||
|
$ pass show asd
|
||||||
|
inlet area crux
|
||||||
|
|
||||||
|
$ file ~/.password-store/asd.gpg
|
||||||
|
```
|
17
rauhala.info/projects/2021-01-21-zettelkast.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
title: zettelkast
|
||||||
|
github: https://github.com/MasseR/zettelkast
|
||||||
|
issues: https://github.com/MasseR/zettelkast/issues
|
||||||
|
badge: https://github.com/MasseR/zettelkast/workflows/Test/badge.svg
|
||||||
|
---
|
||||||
|
|
||||||
|
Command-line tool for managing zettelkast documents. The tool primarily focuses
|
||||||
|
on providing unique ids and showing a graph of document connections. It tries
|
||||||
|
to be as unintrusive as possible.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ zettelkast help
|
||||||
|
$ zettelkast new
|
||||||
|
$ zettelkast list
|
||||||
|
$ zettelkast open <id>
|
||||||
|
```
|
514
rauhala.info/resources/0x9DE6E04ED1918118.txt
Normal file
@ -0,0 +1,514 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
AQQAAQAAALUAAAABAQQAAQAAAAABAAACAQMAAwAAAJoBAAADAQMAAQAAAAYAAAAG
|
||||||
|
AQMAAQAAAAYAAAAVAQMAAQAAAAMAAAABAgQAAQAAAKABAAACAgQAAQAAANYSAAAA
|
||||||
|
AAAACAAIAAgA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgK
|
||||||
|
DBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4z
|
||||||
|
NDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
|
||||||
|
MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAEAALUDASIAAhEBAxEB/8QAHwAA
|
||||||
|
AQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9
|
||||||
|
AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJico
|
||||||
|
KSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJ
|
||||||
|
ipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi
|
||||||
|
4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI
|
||||||
|
CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKR
|
||||||
|
obHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldY
|
||||||
|
WVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0
|
||||||
|
tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMB
|
||||||
|
AAIRAxEAPwCyTg0E0hNNJoAduo3UzNJmgCXdRuqLdS5oAl3UZqHNKDQBLmk3U0bm
|
||||||
|
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
|
||||||
|
pzLw9CHm+xryZ2/pLdGqaAoc2NUCtQnMbLmuoK20O04hLNzLay/J5rlponeVo6i0
|
||||||
|
ZrAae9p1UMOq1GlqUnvry5Ib1segir0S6oekelXi9ommIDWzhoGdGfqaSwQIQSLi
|
||||||
|
6K7dRN0dwSi6eltbUT5dtD1NYXRzIFJhdWhhbGEgKFdvcmsgYWRkcmVzcykgPG1h
|
||||||
|
dHMucmF1aGFsYUByZWxleHNvbHV0aW9ucy5jb20+iQJMBBMBCgA2FiEEldvmTC6m
|
||||||
|
TWsODIwvnebgTtGRgRgFAmEfo5cCGwMECwkIBwQVCgkIBRYCAwEAAh4BAheAAAoJ
|
||||||
|
EJ3m4E7RkYEYSSYP/1+euBleDqO0hEJ3GULsCoSKaocR0JjVC24ydbdrAH6476lv
|
||||||
|
9GK/XXGazusaTtB9c6+hWk7gby8vyl5V+6HR7oVsQOHuLN19yaPRc/Y9npmDMYL1
|
||||||
|
ekxzNgF5S1KP4P4pymCmSDB93MzMWKVVq48xfBULUDKs7nK5wsmhkVzBStWS/bvK
|
||||||
|
IqaMtvyxvv1QJe/N73yjseikp13k+NQx7O+O8tVlRZGq7egNOrNjNm3Qm5npUleG
|
||||||
|
FLzSUN7cEXvrK5foLYtv7JN9ew9To0Y+k7JRftuv8kTZl1WPslDyjtG2ckwQsus/
|
||||||
|
ElL7eKTZmmzVKWRpJ8h4NJQsbv3KVr2Fz2Z83VaLCZErWOvm1R03cRzVeqDp9js/
|
||||||
|
G4iuaTcrfNGdY5cUXdlLx8zYKdQP/skaZ1L2WfcrEJ/CaZuKAGhum81e1T/MgKYG
|
||||||
|
3ArZ0RNdtG3OJ2Ae/gVZN+28bH6AbVausdraP8alO8+UMLvIiUvEvzt7K2o8p5Av
|
||||||
|
6+YJ8CfnkuE68sQqZzHMdgu7VLApqIuIMuI/j9VJg345wVBqR07/xJ0PP6jODoHg
|
||||||
|
ZDPUS8QBFT86VevWYnptwPk5z32OTIpLcqkvgWqHZVTd3iAtZks09rlYgtA8Z/ec
|
||||||
|
5WtsYduR3+r/P1rn+GS/Ot7A0Q2fS0oW0dt6pzVkn3dbWrw8vLkLJKD5TUrttCVN
|
||||||
|
YXRzIFJhdWhhbGEgPG1hdHMucmF1aGFsYUBnbWFpbC5jb20+iQJMBBMBCgA2FiEE
|
||||||
|
ldvmTC6mTWsODIwvnebgTtGRgRgFAmEfo60CGwMECwkIBwQVCgkIBRYCAwEAAh4B
|
||||||
|
AheAAAoJEJ3m4E7RkYEYkoIP/A+qrQG9DFiH57xgtCTaRllPOyN/x/T1Cl4NxbbC
|
||||||
|
8IJUeX3jPSAiC73ErDRD9QoDCzVBcFoxfJzY1YUvj7bOndv/wnjrdIQOQLKqJIs1
|
||||||
|
E0mxcvsuTp19E9K45RxWj9mIuikSh1tvQ6dUqbk1BKRpJMDUFSLq+5Hc45pHWcBM
|
||||||
|
C+Dk71ZGb/Hvk9S6BLIMn16M46s9qSvvajYbAtTUlswb+5L7r0QxRfzm1NaWqys2
|
||||||
|
IGKZp2WUYQ4pMODz8nQEjXcSuzK1xABXhAt50euSFgEI5Hm5W3SEFBn0xxprneVY
|
||||||
|
2+8+j19E9X06/Nz15d0nucCtpX8k5tsRt6jF/JEW3QzrQIA04pe/bliQlPkhNUD2
|
||||||
|
smRust+c4nfZeEi+PX03nLTcnshQGieRDTmpznBSuuclz4r0jjQPP7wIEFZuNmDz
|
||||||
|
Sm7q+rMsT9+s06NPZlLA9+zVLQuAmMxd5iDVMewO58MNl8KUOy4Q3MdIUjZQ8piJ
|
||||||
|
c5txcK874zZvTAY4F0cXI8E3vFicoXd+KKwlU6153DLtuHhwc8gEhktKVTGuvd4J
|
||||||
|
slkUxPa9i3TJO8SKAgjepuDWhdr+Ow7vaV/U4V1dZFvO1qFCCSJ+yd+tzfBqbJZr
|
||||||
|
ClAODrnmS0w7MwhQtvM2peTMvHZ7a1Xje6dEiDx6LTgcYnndI6+PlzXnIaWfzPho
|
||||||
|
uPr+uQINBGEflc8BEACqKTCzl5AadibGzOXl0vVp4PGL4RqIMOmjC328IbiNPkhH
|
||||||
|
2pUkE+uQ6XQpHqCd9S2B7TyKxJKbZ2Qg3UVDxeMaiczw3frt30/pdeNO5npbbqtD
|
||||||
|
40SfxXTDlrZDDJ0jWYMEyHojuotrq5T54UxHatgTl8G9KX4n7bOLkrCpfimy/vYw
|
||||||
|
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
|
||||||
|
QhI/nB5QWaALtbgTQRN0qEGVSjA=
|
||||||
|
=/9Yv
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
@ -10,30 +10,30 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<div class="logo">
|
<!-- <div class="logo"> -->
|
||||||
<a href="/">rauhala.info</a>
|
<!-- <a href="/">rauhala.info</a> -->
|
||||||
</div>
|
<!-- </div> -->
|
||||||
<nav>
|
<nav>
|
||||||
<!-- Git logo from https://git-scm.com/downloads/logos -->
|
<!-- Git logo from https://git-scm.com/downloads/logos -->
|
||||||
<!-- Logo by Jason Long -->
|
<!-- Logo by Jason Long -->
|
||||||
|
<a href="/">Home</a>
|
||||||
|
<a href="/posts.html">Posts</a>
|
||||||
|
<a href="/projects.html">Projects</a>
|
||||||
<a href="https://git.rauhala.info"><img src="/images/git_16.png" alt="git" /></a>
|
<a href="https://git.rauhala.info"><img src="/images/git_16.png" alt="git" /></a>
|
||||||
<a href="/contact.html">Contact</a>
|
<a href="/contact.html">Contact</a>
|
||||||
<a href="/posts.html">Posts</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main role="main">
|
<main role="main">
|
||||||
|
<div>
|
||||||
<h1>$title$</h1>
|
<h1>$title$</h1>
|
||||||
$body$
|
$body$
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
Site proudly generated by
|
Site proudly generated by
|
||||||
<a href="http://jaspervdj.be/hakyll">Hakyll</a>
|
<a href="http://jaspervdj.be/hakyll">Hakyll</a>
|
||||||
<span id="ipfs">and found on IPFS as <em></em></ipfs>
|
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
<script type="application/javascript" src="/js/jquery-3.3.1.min.js"></script>
|
|
||||||
<script type="application/javascript" src="/js/api.js"></script>
|
|
||||||
<script type="application/javascript" src="/js/app.js"></script>
|
|
||||||
</html>
|
</html>
|
7
rauhala.info/templates/post-list.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<ul>
|
||||||
|
$for(items)$
|
||||||
|
<li>
|
||||||
|
<a href="$url$">$title$</a> - $date$
|
||||||
|
</li>
|
||||||
|
$endfor$
|
||||||
|
</ul>
|
8
rauhala.info/templates/post.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<article>
|
||||||
|
<section class="header">
|
||||||
|
Posted on $date$
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
$body$
|
||||||
|
</section>
|
||||||
|
</article>
|
11
rauhala.info/templates/project-list.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<ul>
|
||||||
|
$for(items)$
|
||||||
|
<li>
|
||||||
|
<div class="projectlist">
|
||||||
|
<a href="$url$">$title$</a>
|
||||||
|
<a href="$github$">$if(badge)$<img src="$badge$" />$else$ Github $endif$</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
$endfor$
|
||||||
|
</ul>
|
||||||
|
|
12
rauhala.info/templates/project.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<div class="sidebar-container">
|
||||||
|
<article>
|
||||||
|
<section>
|
||||||
|
$body$
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
<div class="sidebar">
|
||||||
|
<a href="$github$">Github</a>
|
||||||
|
<a href="$issues$">Issues</a>
|
||||||
|
$if(badge)$<img src="$badge$" />$endif$
|
||||||
|
</div>
|
||||||
|
</div>
|
21
release.nix
@ -1,21 +0,0 @@
|
|||||||
{ pkgs ? import <nixpkgs> {} }:
|
|
||||||
|
|
||||||
let
|
|
||||||
haskellPackages = pkgs.haskellPackages;
|
|
||||||
site = pkgs.callPackage ./default.nix {};
|
|
||||||
shell = pkgs.buildEnv {
|
|
||||||
name = "site-shell";
|
|
||||||
paths = [];
|
|
||||||
buildInputs = [
|
|
||||||
haskellPackages.ghcid
|
|
||||||
haskellPackages.hasktags
|
|
||||||
(haskellPackages.ghcWithHoogle (h: site.buildInputs ++ site.propagatedBuildInputs))
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
site = site;
|
|
||||||
shell = shell;
|
|
||||||
}
|
|
@ -1,176 +0,0 @@
|
|||||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
||||||
|
|
||||||
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
|
|
||||||
=VUWT
|
|
||||||
-----END PGP PUBLIC KEY BLOCK-----
|
|
71
site.hs
@ -1,71 +0,0 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
import Data.List (sortOn)
|
|
||||||
import Data.Time (defaultTimeLocale, formatTime)
|
|
||||||
import Hakyll
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
main :: IO ()
|
|
||||||
main = hakyllWith defaultConfiguration{ deployCommand = "ipfs add -Q -r _site" } $do
|
|
||||||
match "images/*" $ do
|
|
||||||
route idRoute
|
|
||||||
compile copyFileCompiler
|
|
||||||
|
|
||||||
match "resources/*" $ do
|
|
||||||
route idRoute
|
|
||||||
compile copyFileCompiler
|
|
||||||
|
|
||||||
match "css/*" $ do
|
|
||||||
route idRoute
|
|
||||||
compile compressCssCompiler
|
|
||||||
|
|
||||||
match "js/*" $ do
|
|
||||||
route idRoute
|
|
||||||
compile compressCssCompiler
|
|
||||||
|
|
||||||
match (fromList ["index.markdown", "contact.markdown"]) $ do
|
|
||||||
route $ setExtension "html"
|
|
||||||
compile $ pandocCompiler
|
|
||||||
>>= loadAndApplyTemplate "templates/default.html" defaultContext
|
|
||||||
>>= relativizeUrls
|
|
||||||
|
|
||||||
match "posts/*" $ do
|
|
||||||
route $ setExtension "html"
|
|
||||||
compile $ pandocCompiler
|
|
||||||
>>= loadAndApplyTemplate "templates/post.html" postCtx
|
|
||||||
>>= loadAndApplyTemplate "templates/default.html" postCtx
|
|
||||||
>>= relativizeUrls
|
|
||||||
|
|
||||||
create ["posts.html"] $ do
|
|
||||||
route idRoute
|
|
||||||
compile $ do
|
|
||||||
posts <- modFirst =<< loadAll "posts/*"
|
|
||||||
let archiveCtx =
|
|
||||||
listField "posts" postCtx (return posts) <>
|
|
||||||
constField "title" "Posts" <>
|
|
||||||
defaultContext
|
|
||||||
|
|
||||||
makeItem ""
|
|
||||||
>>= loadAndApplyTemplate "templates/guides.html" archiveCtx
|
|
||||||
>>= loadAndApplyTemplate "templates/default.html" archiveCtx
|
|
||||||
>>= relativizeUrls
|
|
||||||
|
|
||||||
|
|
||||||
match "templates/*" $ compile templateBodyCompiler
|
|
||||||
|
|
||||||
modFirst :: [Item a] -> Compiler [Item a]
|
|
||||||
modFirst = fmap reverse . modified
|
|
||||||
where
|
|
||||||
modified = sortByM (getItemModificationTime . itemIdentifier)
|
|
||||||
sortByM f xs = map fst . sortOn snd <$> mapM (\x -> (,) x <$> f x) xs
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
postCtx :: Context String
|
|
||||||
postCtx =
|
|
||||||
dateField "date" "%B %e, %Y" <>
|
|
||||||
modifiedField "modified" "%B %e, %Y" <>
|
|
||||||
defaultContext
|
|
||||||
where
|
|
||||||
modifiedField key format = field key $ \i -> do
|
|
||||||
time <- getItemModificationTime $ itemIdentifier i
|
|
||||||
return $ formatTime defaultTimeLocale format time
|
|
249
site/.stylish-haskell.yaml
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
# stylish-haskell configuration file
|
||||||
|
# ==================================
|
||||||
|
|
||||||
|
# The stylish-haskell tool is mainly configured by specifying steps. These steps
|
||||||
|
# are a list, so they have an order, and one specific step may appear more than
|
||||||
|
# once (if needed). Each file is processed by these steps in the given order.
|
||||||
|
steps:
|
||||||
|
# Convert some ASCII sequences to their Unicode equivalents. This is disabled
|
||||||
|
# by default.
|
||||||
|
# - unicode_syntax:
|
||||||
|
# # In order to make this work, we also need to insert the UnicodeSyntax
|
||||||
|
# # language pragma. If this flag is set to true, we insert it when it's
|
||||||
|
# # not already present. You may want to disable it if you configure
|
||||||
|
# # language extensions using some other method than pragmas. Default:
|
||||||
|
# # true.
|
||||||
|
# add_language_pragma: true
|
||||||
|
|
||||||
|
# Align the right hand side of some elements. This is quite conservative
|
||||||
|
# and only applies to statements where each element occupies a single
|
||||||
|
# line.
|
||||||
|
- simple_align:
|
||||||
|
cases: false
|
||||||
|
top_level_patterns: false
|
||||||
|
records: false
|
||||||
|
|
||||||
|
# Import cleanup
|
||||||
|
- imports:
|
||||||
|
# There are different ways we can align names and lists.
|
||||||
|
#
|
||||||
|
# - global: Align the import names and import list throughout the entire
|
||||||
|
# file.
|
||||||
|
#
|
||||||
|
# - file: Like global, but don't add padding when there are no qualified
|
||||||
|
# imports in the file.
|
||||||
|
#
|
||||||
|
# - group: Only align the imports per group (a group is formed by adjacent
|
||||||
|
# import lines).
|
||||||
|
#
|
||||||
|
# - none: Do not perform any alignment.
|
||||||
|
#
|
||||||
|
# Default: global.
|
||||||
|
align: none
|
||||||
|
|
||||||
|
# The following options affect only import list alignment.
|
||||||
|
#
|
||||||
|
# List align has following options:
|
||||||
|
#
|
||||||
|
# - after_alias: Import list is aligned with end of import including
|
||||||
|
# 'as' and 'hiding' keywords.
|
||||||
|
#
|
||||||
|
# > import qualified Data.List as List (concat, foldl, foldr, head,
|
||||||
|
# > init, last, length)
|
||||||
|
#
|
||||||
|
# - with_alias: Import list is aligned with start of alias or hiding.
|
||||||
|
#
|
||||||
|
# > import qualified Data.List as List (concat, foldl, foldr, head,
|
||||||
|
# > init, last, length)
|
||||||
|
#
|
||||||
|
# - new_line: Import list starts always on new line.
|
||||||
|
#
|
||||||
|
# > import qualified Data.List as List
|
||||||
|
# > (concat, foldl, foldr, head, init, last, length)
|
||||||
|
#
|
||||||
|
# Default: after_alias
|
||||||
|
list_align: new_line
|
||||||
|
|
||||||
|
# Right-pad the module names to align imports in a group:
|
||||||
|
#
|
||||||
|
# - true: a little more readable
|
||||||
|
#
|
||||||
|
# > import qualified Data.List as List (concat, foldl, foldr,
|
||||||
|
# > init, last, length)
|
||||||
|
# > import qualified Data.List.Extra as List (concat, foldl, foldr,
|
||||||
|
# > init, last, length)
|
||||||
|
#
|
||||||
|
# - false: diff-safe
|
||||||
|
#
|
||||||
|
# > import qualified Data.List as List (concat, foldl, foldr, init,
|
||||||
|
# > last, length)
|
||||||
|
# > import qualified Data.List.Extra as List (concat, foldl, foldr,
|
||||||
|
# > init, last, length)
|
||||||
|
#
|
||||||
|
# Default: true
|
||||||
|
pad_module_names: false
|
||||||
|
|
||||||
|
# Long list align style takes effect when import is too long. This is
|
||||||
|
# determined by 'columns' setting.
|
||||||
|
#
|
||||||
|
# - inline: This option will put as much specs on same line as possible.
|
||||||
|
#
|
||||||
|
# - new_line: Import list will start on new line.
|
||||||
|
#
|
||||||
|
# - new_line_multiline: Import list will start on new line when it's
|
||||||
|
# short enough to fit to single line. Otherwise it'll be multiline.
|
||||||
|
#
|
||||||
|
# - multiline: One line per import list entry.
|
||||||
|
# Type with constructor list acts like single import.
|
||||||
|
#
|
||||||
|
# > import qualified Data.Map as M
|
||||||
|
# > ( empty
|
||||||
|
# > , singleton
|
||||||
|
# > , ...
|
||||||
|
# > , delete
|
||||||
|
# > )
|
||||||
|
#
|
||||||
|
# Default: inline
|
||||||
|
long_list_align: new_line_multiline
|
||||||
|
|
||||||
|
# Align empty list (importing instances)
|
||||||
|
#
|
||||||
|
# Empty list align has following options
|
||||||
|
#
|
||||||
|
# - inherit: inherit list_align setting
|
||||||
|
#
|
||||||
|
# - right_after: () is right after the module name:
|
||||||
|
#
|
||||||
|
# > import Vector.Instances ()
|
||||||
|
#
|
||||||
|
# Default: inherit
|
||||||
|
empty_list_align: inherit
|
||||||
|
|
||||||
|
# List padding determines indentation of import list on lines after import.
|
||||||
|
# This option affects 'long_list_align'.
|
||||||
|
#
|
||||||
|
# - <integer>: constant value
|
||||||
|
#
|
||||||
|
# - module_name: align under start of module name.
|
||||||
|
# Useful for 'file' and 'group' align settings.
|
||||||
|
list_padding: 7
|
||||||
|
|
||||||
|
# Separate lists option affects formatting of import list for type
|
||||||
|
# or class. The only difference is single space between type and list
|
||||||
|
# of constructors, selectors and class functions.
|
||||||
|
#
|
||||||
|
# - true: There is single space between Foldable type and list of it's
|
||||||
|
# functions.
|
||||||
|
#
|
||||||
|
# > import Data.Foldable (Foldable (fold, foldl, foldMap))
|
||||||
|
#
|
||||||
|
# - false: There is no space between Foldable type and list of it's
|
||||||
|
# functions.
|
||||||
|
#
|
||||||
|
# > import Data.Foldable (Foldable(fold, foldl, foldMap))
|
||||||
|
#
|
||||||
|
# Default: true
|
||||||
|
separate_lists: false
|
||||||
|
|
||||||
|
# Space surround option affects formatting of import lists on a single
|
||||||
|
# line. The only difference is single space after the initial
|
||||||
|
# parenthesis and a single space before the terminal parenthesis.
|
||||||
|
#
|
||||||
|
# - true: There is single space associated with the enclosing
|
||||||
|
# parenthesis.
|
||||||
|
#
|
||||||
|
# > import Data.Foo ( foo )
|
||||||
|
#
|
||||||
|
# - false: There is no space associated with the enclosing parenthesis
|
||||||
|
#
|
||||||
|
# > import Data.Foo (foo)
|
||||||
|
#
|
||||||
|
# Default: false
|
||||||
|
space_surround: false
|
||||||
|
|
||||||
|
# Language pragmas
|
||||||
|
- language_pragmas:
|
||||||
|
# We can generate different styles of language pragma lists.
|
||||||
|
#
|
||||||
|
# - vertical: Vertical-spaced language pragmas, one per line.
|
||||||
|
#
|
||||||
|
# - compact: A more compact style.
|
||||||
|
#
|
||||||
|
# - compact_line: Similar to compact, but wrap each line with
|
||||||
|
# `{-#LANGUAGE #-}'.
|
||||||
|
#
|
||||||
|
# Default: vertical.
|
||||||
|
style: vertical
|
||||||
|
|
||||||
|
# Align affects alignment of closing pragma brackets.
|
||||||
|
#
|
||||||
|
# - true: Brackets are aligned in same column.
|
||||||
|
#
|
||||||
|
# - false: Brackets are not aligned together. There is only one space
|
||||||
|
# between actual import and closing bracket.
|
||||||
|
#
|
||||||
|
# Default: true
|
||||||
|
align: false
|
||||||
|
|
||||||
|
# stylish-haskell can detect redundancy of some language pragmas. If this
|
||||||
|
# is set to true, it will remove those redundant pragmas. Default: true.
|
||||||
|
remove_redundant: true
|
||||||
|
|
||||||
|
# Replace tabs by spaces. This is disabled by default.
|
||||||
|
# - tabs:
|
||||||
|
# # Number of spaces to use for each tab. Default: 8, as specified by the
|
||||||
|
# # Haskell report.
|
||||||
|
# spaces: 8
|
||||||
|
|
||||||
|
# Remove trailing whitespace
|
||||||
|
- trailing_whitespace: {}
|
||||||
|
|
||||||
|
# Squash multiple spaces between the left and right hand sides of some
|
||||||
|
# elements into single spaces. Basically, this undoes the effect of
|
||||||
|
# simple_align but is a bit less conservative.
|
||||||
|
# - squash: {}
|
||||||
|
|
||||||
|
# A common setting is the number of columns (parts of) code will be wrapped
|
||||||
|
# to. Different steps take this into account. Default: 80.
|
||||||
|
columns: 80
|
||||||
|
|
||||||
|
# By default, line endings are converted according to the OS. You can override
|
||||||
|
# preferred format here.
|
||||||
|
#
|
||||||
|
# - native: Native newline format. CRLF on Windows, LF on other OSes.
|
||||||
|
#
|
||||||
|
# - lf: Convert to LF ("\n").
|
||||||
|
#
|
||||||
|
# - crlf: Convert to CRLF ("\r\n").
|
||||||
|
#
|
||||||
|
# Default: native.
|
||||||
|
newline: native
|
||||||
|
|
||||||
|
# Sometimes, language extensions are specified in a cabal file or from the
|
||||||
|
# command line instead of using language pragmas in the file. stylish-haskell
|
||||||
|
# needs to be aware of these, so it can parse the file correctly.
|
||||||
|
#
|
||||||
|
# No language extensions are enabled by default.
|
||||||
|
language_extensions:
|
||||||
|
- RecordWildCards
|
||||||
|
- TemplateHaskell
|
||||||
|
- QuasiQuotes
|
||||||
|
- LambdaCase
|
||||||
|
- TupleSections
|
||||||
|
- MultiParamTypeClasses
|
||||||
|
- TypeApplications
|
||||||
|
- DataKinds
|
||||||
|
- TypeFamilies
|
||||||
|
- FlexibleContexts
|
||||||
|
- NamedFieldPuns
|
||||||
|
- MultiWayIf
|
||||||
|
- PolyKinds
|
||||||
|
- ExplicitForAll
|
||||||
|
- FunctionalDependencies
|
||||||
|
- ExplicitNamespaces
|
||||||
|
- ScopedTypeVariables
|
||||||
|
- ExistentialQuantification
|
||||||
|
- InstanceSigs
|
||||||
|
- GeneralizedNewtypeDeriving
|
||||||
|
- BangPatterns
|
||||||
|
|
107
site/app/site.hs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE RecordWildCards #-}
|
||||||
|
{-# LANGUAGE StrictData #-}
|
||||||
|
import Hakyll
|
||||||
|
|
||||||
|
import Data.List
|
||||||
|
(isPrefixOf, isSuffixOf)
|
||||||
|
|
||||||
|
import System.FilePath
|
||||||
|
(takeFileName)
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
main :: IO ()
|
||||||
|
main = hakyllWith defaultConfiguration{ignoreFile = ignore} $ do
|
||||||
|
match "well-known/*" $ do
|
||||||
|
route (customRoute (prepend '.'. toFilePath))
|
||||||
|
compile copyFileCompiler
|
||||||
|
|
||||||
|
match "images/*" $ do
|
||||||
|
route idRoute
|
||||||
|
compile copyFileCompiler
|
||||||
|
|
||||||
|
match "resources/*" $ do
|
||||||
|
route idRoute
|
||||||
|
compile copyFileCompiler
|
||||||
|
|
||||||
|
match "css/*" $ do
|
||||||
|
route idRoute
|
||||||
|
compile compressCssCompiler
|
||||||
|
|
||||||
|
match "js/*" $ do
|
||||||
|
route idRoute
|
||||||
|
compile compressCssCompiler
|
||||||
|
|
||||||
|
match "posts/*" $ do
|
||||||
|
route $ setExtension "html"
|
||||||
|
compile $ pandocCompiler
|
||||||
|
>>= loadAndApplyTemplate "templates/post.html" postContext
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" defaultContext
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
match "projects/*" $ do
|
||||||
|
route $ setExtension "html"
|
||||||
|
compile $ pandocCompiler
|
||||||
|
>>= loadAndApplyTemplate "templates/project.html" postContext
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" defaultContext
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
|
||||||
|
match (fromList ["index.markdown", "contact.markdown"]) $ do
|
||||||
|
route $ setExtension "html"
|
||||||
|
compile $ pandocCompiler
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" defaultContext
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
archive $ Archive { output = "posts.html"
|
||||||
|
, input = "posts/*"
|
||||||
|
, title = "Posts"
|
||||||
|
, template = "templates/post-list.html"
|
||||||
|
, context = postContext
|
||||||
|
}
|
||||||
|
|
||||||
|
archive $ Archive { output = "projects.html"
|
||||||
|
, input = "projects/*"
|
||||||
|
, title = "Projects"
|
||||||
|
, template = "templates/project-list.html"
|
||||||
|
, context = postContext
|
||||||
|
}
|
||||||
|
|
||||||
|
match "templates/*" $ compile templateBodyCompiler
|
||||||
|
where
|
||||||
|
|
||||||
|
postContext :: Context String
|
||||||
|
postContext = dateField "date" "%B %e, %Y" <> defaultContext
|
||||||
|
ignore :: FilePath -> Bool
|
||||||
|
ignore path = any ($ takeFileName path)
|
||||||
|
[ ("." `isPrefixOf`)
|
||||||
|
, ("#" `isPrefixOf`)
|
||||||
|
, ("~" `isSuffixOf`)
|
||||||
|
, (".swp" `isSuffixOf`)
|
||||||
|
]
|
||||||
|
|
||||||
|
data Archive
|
||||||
|
= Archive { output :: Identifier
|
||||||
|
, input :: Pattern
|
||||||
|
, title :: String
|
||||||
|
, template :: Identifier
|
||||||
|
, context :: Context String
|
||||||
|
}
|
||||||
|
|
||||||
|
archive :: Archive -> Rules ()
|
||||||
|
archive Archive{..} = create [output] $ do
|
||||||
|
route idRoute
|
||||||
|
compile $ do
|
||||||
|
let itemsContext =
|
||||||
|
listField "items" context items
|
||||||
|
<> constField "title" title
|
||||||
|
<> defaultContext
|
||||||
|
items = recentFirst =<< loadAll input
|
||||||
|
makeItem ""
|
||||||
|
>>= loadAndApplyTemplate template itemsContext
|
||||||
|
>>= loadAndApplyTemplate "templates/default.html" itemsContext
|
||||||
|
>>= relativizeUrls
|
||||||
|
|
||||||
|
prepend :: a -> [a] -> [a]
|
||||||
|
prepend = (:)
|
10
site/default.nix
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{ mkDerivation, base, filepath, hakyll, lib, time }:
|
||||||
|
mkDerivation {
|
||||||
|
pname = "site";
|
||||||
|
version = "0.1.0.0";
|
||||||
|
src = ./.;
|
||||||
|
isLibrary = false;
|
||||||
|
isExecutable = true;
|
||||||
|
executableHaskellDepends = [ base filepath hakyll time ];
|
||||||
|
license = lib.licenses.bsd3;
|
||||||
|
}
|
@ -9,8 +9,10 @@ maintainer: mats.rauhala@iki.fi
|
|||||||
|
|
||||||
executable site
|
executable site
|
||||||
main-is: site.hs
|
main-is: site.hs
|
||||||
|
hs-source-dirs: app
|
||||||
build-depends: base == 4.*
|
build-depends: base == 4.*
|
||||||
, hakyll >= 4.10
|
, hakyll >= 4.10
|
||||||
, time
|
, time
|
||||||
|
, filepath
|
||||||
ghc-options: -threaded
|
ghc-options: -threaded
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
33
support/deploy-rauhala-info.sh
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!@bash@/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
nix build .#rauhala-info
|
||||||
|
|
||||||
|
API=/ip4/127.0.0.1/tcp/5001
|
||||||
|
|
||||||
|
function upload() {
|
||||||
|
echo "Uploading.."
|
||||||
|
hash=$(ipfs --api $API add -r result/share --pin=false -Q)
|
||||||
|
}
|
||||||
|
|
||||||
|
function pin() {
|
||||||
|
echo "Pinning"
|
||||||
|
ipfs --api $API pin remote rm --service=pinata --cid="$hash"
|
||||||
|
ipfs --api $API pin remote add --service=pinata --name=rauhala.info "$hash"
|
||||||
|
}
|
||||||
|
|
||||||
|
function publish() {
|
||||||
|
echo "Updating name"
|
||||||
|
ipfs --api $API name publish --key=rauhala.info "$hash"
|
||||||
|
}
|
||||||
|
|
||||||
|
upload
|
||||||
|
|
||||||
|
pin &
|
||||||
|
|
||||||
|
publish &
|
||||||
|
|
||||||
|
wait
|
||||||
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
Me writing out interesting ideas and experiments.
|
|
||||||
|
|
||||||
$partial("templates/post-list.html")$
|
|
@ -1,7 +0,0 @@
|
|||||||
<ul>
|
|
||||||
$for(posts)$
|
|
||||||
<li>
|
|
||||||
<a href="$url$">$title$</a> - $modified$
|
|
||||||
</li>
|
|
||||||
$endfor$
|
|
||||||
</ul>
|
|
@ -1,11 +0,0 @@
|
|||||||
<article>
|
|
||||||
<section class="header">
|
|
||||||
Posted on $date$, modified on $modified$
|
|
||||||
$if(author)$
|
|
||||||
by $author$
|
|
||||||
$endif$
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
$body$
|
|
||||||
</section>
|
|
||||||
</article>
|
|