Skip to content

Instantly share code, notes, and snippets.

@derekmorr
derekmorr / ch17.hs
Last active February 10, 2017 01:25
ch17.hs
module Ch17 where
import Control.Applicative
import Data.List (elemIndex)
import Data.Monoid
-- 1
added :: Maybe Integer
added = (+3) <$> (lookup 3 $ zip [1, 2, 3] [4, 5, 6])

Last week we refactored some Python code that parses CSV files and loads records into a database. We ended up with two general groups of code.

One group (lines 24 - 43) is a series of small functions that extract various data types (booleans, timestamps, etc) from CSV fields. The other group is a large function (lines 46 - 92) that extracts individual fields and builds a model object. I expressed frustration that this latter function was so long.

def build_nessus_object(row, heading_map):
    """process a row of data and return a Nessus object"""
    # parameters which are processed as-is from the csv
    normal_params = {
        'plugin' : 'Plugin',
module Lib where
-- 18.7 Question 1
data Nope a = NopeDotJpg deriving (Eq, Show)
instance Functor Nope where
fmap _ NopeDotJpg = NopeDotJpg
instance Applicative Nope where
@derekmorr
derekmorr / types-tests-sorting.md
Created March 11, 2017 02:39
Thoughts on types & tests in light of a sorting problem.

In slack today, I said

i’ve never been a fan of using integers to indicate ordering. there are billions of values in an int32 that all map onto the same meaning (greater than) or (less than). so much possibility for bugs

i like the way Haskell does it — use an enum (LT, EQ, GT) — that way there’s no confusion and the compiler can ensure you’ve handled all possibilities.

I thought I should explain this.

I reworked the ruby sort code to look like this:

@derekmorr
derekmorr / opening_a_file.md
Last active September 19, 2018 02:42
opening_a_file.md

Opening a file

A comparison of error handling strategies in a few popular languages. We look at how opening a file is handled as a specific example.

C

The open(2) API is the POSIX standard for opening files in C.

int open(const char *path, int oflag, ...);
@derekmorr
derekmorr / RefinedPathBindable.scala
Created May 23, 2017 23:51
Play 2.x PathBinable for Refined Types
package controllers
import scala.language.higherKinds
import eu.timepit.refined.api.{RefType, Validate}
import play.api.mvc.PathBindable
object RefinedPathBindable {
@derekmorr
derekmorr / RefinedJson.scala
Created June 2, 2017 14:38
helping in gitter
import java.time.Instant
import com.lunaryorn.refined.play.json._
import controllers.json.types.NumericString
import eu.timepit.refined.W
import eu.timepit.refined.api.Refined
import eu.timepit.refined.boolean.And
import eu.timepit.refined.char.Digit
import eu.timepit.refined.collection.{Forall, NonEmpty, Size}
import play.api.libs.json.{Format, Json}
@derekmorr
derekmorr / ShoppingCart.scala
Created August 4, 2017 12:25
shopping cart kata
case class MultiPrice(qty: Int, price: Int)
case class PriceData(
itemPrices: Map[Char, Int],
multiPrices: Map[Char, MultiPrice]
)
object ShoppingCart {
def checkout(basket: String, priceData: PriceData): Int = {
val itemCounts = basket.groupBy(identity).mapValues(_.length)
### Keybase proof
I hereby claim:
* I am derekmorr on github.
* I am derekmorr (https://keybase.io/derekmorr) on keybase.
* I have a public key ASBA5cJyOy9r28oBcHIJCnkvU2AbKAbiBxQWwMZQ2XcnvQo
To claim this, I am signing this object:
@derekmorr
derekmorr / EquationalReasoning.md
Last active November 2, 2017 21:19
Equational Reasoning

Overview

One of the benefits of functional programming is that it's much simpler to figure out how your code will run. Because functional languages are based on math, you're really definining functions in terms of equality. As such, you can substitute terms for one another. In this example, I'll use Haskell, because the syntax highlights this point, but the principle applies in multiple languages (Erlang, Elixir, OCaml, etc).

In Haskell, when you write x = 5 that means that x and 5 are the same thing. As such, whereever you have an x in your program, you can replace it with 5, or vice-versa. Because x and 5 are the same, these substitutions don't break your program. This ability to substitute terms for one another is called equational reasoning.

In fact, this is how Haskell runs your program — it repeatedly applies substitutions until it has one giant main function.

I'm going to work through a short example using linked lists.