Skip to content

Instantly share code, notes, and snippets.

View owickstrom's full-sized avatar

Oskar Wickström owickstrom

View GitHub Profile
@owickstrom
owickstrom / .gitignore
Last active September 4, 2017 04:43
Compile-time checking globally loaded scripts for Yesod
.stack-work
@owickstrom
owickstrom / README.md
Last active May 20, 2017 15:49
Servant-like routing in PureScript without ordering requirements

Servant-like routing in PureScript without ordering requirements

With Servant-style routing, the ordering of endpoints in types must line up with handlers on the value level. Destructuring clients and link structures derived from a routing type cannot be done without introducing coupling to the ordering of the routing type.

This experiment tries to remove that ordering issue, by using named resources and methods on the type level, in combination with PureScript's records (constrained by RowCons) at the value level. The ordering no longer matter when we give handlers in a record. We could also implement link or client deriving functions that would extract specific clients based on a given name. All name checks are done at compile time.

@owickstrom
owickstrom / SafeForm.purs
Created February 28, 2017 19:06
Type-safe forms draft
module Examples.SafeForm where
import Control.IxMonad ((:*>))
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE)
import Control.Monad.Except (ExceptT)
import Data.Foldable (traverse_)
import Data.Maybe (Maybe(..), maybe)
import Data.MediaType.Common (textHTML)
import Data.Monoid (mempty)
@owickstrom
owickstrom / keybase.md
Created February 14, 2017 06:04
keybase.md

Keybase proof

I hereby claim:

  • I am owickstrom on github.
  • I am owickstrom (https://keybase.io/owickstrom) on keybase.
  • I have a public key whose fingerprint is 571E 0B73 FDB5 B163 DD48 7576 CEDE 3357 E0C5 F53E

To claim this, I am signing this object:

@owickstrom
owickstrom / Main.purs
Last active December 8, 2016 20:07
PureScript record and mutual recursion problem with Instances
module Main where
import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
type R m = { f ∷ Int → m Int }
makeDecr ∷ ∀ m. Monad m ⇒ R m → R m
makeDecr r = { f: \n → if n > 0 then r.f (n - 1) else pure n }
@owickstrom
owickstrom / compile-error.txt
Created December 8, 2016 19:17
compile-error.txt
No type class instance was found for
Control.Monad.Monad m0
while checking that expression { path: [ "contact"
]
, GET: handler (\conn ->
...
)
@owickstrom
owickstrom / composing-alt-functions.md
Last active November 28, 2016 17:16
Composing Alt Functions

What I want is to "compose" functions taking some argument and returning an Alt value, like a -> m b where Alt b. The resulting value should be a function from a -> m b. The implementation below does that, but I was wondering if there's a better way? I'm thinking that maybe I could create a newtype wrapper around these functions, and an Alt instance for that type, but I haven't gotten that to work, and I'm not sure it's a good approach.

@owickstrom
owickstrom / SafeWeb.purs
Last active November 13, 2016 14:46
Safe web routes in PureScript
module SafeWeb where
import Prelude
import Data.Array (filter)
import Data.Leibniz (type (~))
import Data.String (Pattern(Pattern), split, joinWith)
type Path = Array String
pathToHtml :: Path -> String
@owickstrom
owickstrom / TypeSynonymsProblem.purs
Created October 29, 2016 12:26
PureScript type synonym problem with effect kind
module TypeSynonymsProblem where
import Prelude
import Control.Monad.Eff (Eff)
import Data.Either (Either)
import Data.Tuple (Tuple(Tuple))
type Foo e a a' b b' = Eff e (Tuple a b) -> Eff e (Tuple a' b')
type Bar e a a' b b' = Eff e (Either a b) -> Eff e (Either a' b')
@owickstrom
owickstrom / Name.idr
Created October 13, 2016 05:52
Idris String with validation?
-- A data type wrapping a non-empty string
data Name : Type where
MkName : (s : String) -> (not (s == "") = True) -> Name
-- Some function that expects a valid Name
test : Name -> String
test (MkName s _) = s
-- Usage of that function. Do I need Refl here? Any better way of doing this?
foo : String