Skip to content

Instantly share code, notes, and snippets.

@chrislewis
chrislewis / Rel.scala
Created February 9, 2021 20:12
An encoding of typesafe and dynamic composition of a finite set of behaviors
import scala.language.implicitConversions
/**
* A hypothetical type that may possess any combination of several properties, each encoded as a trait specifying
* that property. Our example type may have any of these properties:
*
* links: Set[String]
* meta: Map[String, String]
* other: Int
sumTwoTrailRec (x : xs) (y : ys) total carry =
sumTwoTrailRec xs ys ((mod sum 10) : total) nextCarry where
sum = x + y + carry
nextCarry = div sum 10
sumTwoTrailRec (x : xs) [] total carry =
sumTwoTrailRec xs [] ((mod (x + carry) 10) : total) (div (x + carry) 10)
sumTwoTrailRec [] (y : ys) total carry =
sumTwoTrailRec [] ys ((mod (y + carry) 10) : total) (div (y + carry) 10)
sumTwoTrailRec [] [] total carry =
reverse $ if carry > 0 then (carry : total) else total
-- solves bug of (9 + 1) in the case of a carry and mismatched list lengths
addTwoNumbers (l1 : tail1) (l2 : tail2) carry =
(mod sum 10) : (addTwoNumbers tail1 tail2 newCarry) where
sum = l1 + l2 + carry
newCarry = div sum 10
addTwoNumbers (l1 : tail1) [] carry =
(mod (l1 + carry) 10) : (addTwoNumbers tail1 [] (div (l1 + carry) 10))
addTwoNumbers [] (l2 : tail2) carry =
(mod (l2 + carry) 10) : (addTwoNumbers [] tail2 (div (l2 + carry) 10))
addTwoNumbers [] [] carry =
sumTwoFoldl :: [Int] -> [Int] -> [Int]
sumTwoFoldl x y =
let (sum, carry) = foldl accum ([], 0) $ zip x y
accum (total, carry) (x, y) =
let t = x + y + carry
(n, nc) =
if t > 9
then (t - 10, 1)
else (t, 0)
in (n : total, nc)
sumTwo :: [Int] -> [Int] -> [Int]
sumTwo x y = doit x y [] 0
where
doit [] [] sum 0 = reverse sum
doit [] [] sum carry = doit [] [] (carry : sum) 0
doit (x : xs) (y : ys) sum carry =
let tot = x + y + carry
(n, nc) =
if tot > 9
then (tot - 10, 1)
/** A boxed union of 3 types; same principle applies for > 3. */
sealed trait OneOf3[A, B, C] {
/** There are plenty of useful methods we could define, but folds provides
an alternative to explicit pattern matching and a basis for other
useful things. */
def fold[X](fax: A => X, fbx: B => X, fcx: C => X): X
}
/* Implementations are straight forward: */
# Zero to Dockerized Nexus on AWS.
# We use the stock nexus image (https://registry.hub.docker.com/u/sonatype/nexus/)
# as well as the stock Linux AMI (as of this writing https://aws.amazon.com/amazon-linux-ami/2014.09-release-notes/).
# We also assume you have configured an AWS identity, key pair, a security
# group that allows inbound TCP/8081, and that you have associated these with
# the instance.
sudo yum install docker
sudo service docker start
# Zero to Dockerized Jenkins on AWS.
# We use the stock docker image (https://registry.hub.docker.com/_/jenkins/)
# as well as the stock Linux AMI (as of this writing https://aws.amazon.com/amazon-linux-ami/2014.09-release-notes/).
# We also assume you have configured an AWS identity, key pair, a security
# group that allows inbound TCP/8080, and that you have associated these with
# the instance.
sudo yum install docker
sudo service docker start
object Fλip {
val tParams = (1 to 23).map { i =>
(i + 'A' - 1).toChar
}
def getParams(arity: Int): IndexedSeq[Char] =
(0 to arity).map(tParams(_))
def getTypeSig(seq: IndexedSeq[Char]) =
s"""(${seq.init.mkString(",")}) => ${seq.last}"""
import scala.language.higherKinds
trait Bifunctor[BF[_, _]] {
def bimap[A, B, C, D](bf: BF[A, C], fab: A => B, fcd: C => D): BF[B, D]
/* Mapping over one of the sides is convenient and can be implemented easily
in terms of `bimap`. */
/** Map over the "first" side, transforming the type and potentially the value
(if the BF instance is of the "first" type, natrually.) */