Article topics:
module Main where | |
import Prelude | |
import Data.Array.NonEmpty (NonEmptyArray, (..)) | |
import Data.Traversable (class Traversable, sequence) | |
import Effect (Effect) | |
import Effect.Console (log) | |
import Prelude as P |
The question of "How do I design my application in Haskell?" comes up a lot. There's a bunch of perspectives and choices, so it makes sense that it's difficult to choose just one. Do I use plain monad transformers, mtl
, just pass the parameters manually and use IO
for everything, the ReaderT
design pattern, free monads, freer monads, some other kind of algebraic effect system?!
The answer is: why not both/all?
Lately, I've been centering on a n application design architecture with roughly three layers:
newtype AppT m a = AppT { unAppT :: ReaderT YourStuff m a } deriving ............
The ReaderT
Design Pattern, essentially. This is what everything gets boiled down to, and what everything eventually gets interpreted in. This type is the backbone of your app. For some components, you carry around some info/state (consider [MonadMetrics
](https://hackage
module Main where | |
import Type.Prelude | |
import Type.Row | |
import Type.Data.Boolean | |
import Type.Data.Symbol as Symbol | |
import Data.Newtype | |
data RProxy (r :: # Type) = RProxy | |
data RLProxy (rl :: RowList) = RLProxy |
"For services to the PureScript Community, Gary Burgess!"
You've done it, Gary. Moore, Lineker, Coleman, and now Burgess. All the work was worth it.
The halls erupted with praise. Children dressed as Space Ghost, teens with "I only get high on
Halogen
" t-shirts, a giant banner held aloft with the message, "Tuple @garyb me
". Through
the noise of the crowds and Phil's uninterpretable Northern accent, he barely managed to hear
his theme tu-
BZZP. BZZP.
-- | Binary operation | |
class Magma a where | |
op ∷ a → a → a | |
-- | Associativity: `∀ a b. (a • b) • c = a • (b • c)` | |
class Magma a ⇐ Associative a | |
-- | Identity: `∀ a. a • identity = a && identity • a = a` | |
class Magma a ⇐ Identity a where | |
identity ∷ a |
module Main where | |
-- | JSON is an incredibly simple format. Even its lists are untyped. | |
-- | As with all languages, functional programming encourages us to | |
-- | make a domain-specific language (or DSL) to capture the "ideas" | |
-- | of the language, which we can then use to talk about its content. | |
-- | In this little snippet, we'll build a JSON DSL, transform it into | |
-- | a recursive structure, and then use that result to generate some |
--- | |
apiVersion: extensions/v1beta1 | |
kind: Deployment | |
metadata: | |
name: example | |
spec: | |
replicas: 2 | |
selector: | |
matchLabels: | |
app: example |
#!/bin/bash | |
# Copyright © 2017 Google Inc. | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software |
module Main where | |
import Prelude | |
import Control.Monad.Eff (Eff) | |
import Control.Monad.Eff.Console (CONSOLE, logShow) | |
import Data.Either (Either(..)) | |
import Data.Foldable (elem, notElem) | |
import Data.Int (toNumber) | |
import Data.Traversable (traverse) | |
import Data.Validation.Semigroup (invalid) |