Sounds like BayHAC was interesting.
Jed on variance (in Scala)
Variance is essentially about substitution or sub-typing. A thing that produces
a Super
may be replaced with a thing that takes Sub
. A think that that
takes Sub
may be replaces by a thing that takes `Super.
Rat -> Real <: Int -> Complex
Reference to
Be liberal in what you accept and conservative in what you produce.
Use site variance in Java
final function Option<a>
In Scala:
List[+A]
Function[-T1, +R]
Kleisli[M[+_], -A, +B]
Eg:
class GPar
class Par extends GPar
class Child extends Par
class Box[+A]
def foo(x:Bor[Par]):
foo(Box[Child])
foo(Box[GPar]) // error
f
trait Box[+A] {
def get: A
def take(a: A) // Error
}
trait Box[-A] {
def get: A
def take(a: A)
}
Functor
trait Functor[F[_]] {
def map[A,B](a: F[A])(f: A => B): F[B]
}
This is actually a contra-variant functor.
trait Contravariant[F[_]] {
def contramap[A,B](r: R[A])(f: B=>A): F[B]
}
Variance in mutable values:
Two type variables. One goes up (things coming out?), one goes down (things going in?).
http://biosimilarity.blogspot.com.au/2011/05/of-monads-and-games.html
Tim on monoid
class Monoid a where
mempty :: a
mappend :: a -> a -> a
Obeys laws
mappend a mempty == a
mappend mempty a == a
mappend a (mappend b c) == mappend (mappend a b) c
Given types may have multiple monoids: numbers have (+, 0) and (*, 1).
Define monoids to do min, max, count on the pattern of Sum
and Product
.
Have a smart constructor for each
The foldable type-class makes fold polymorphic.
class Foldable t where
foldMap :: Monoid m => (a -> m) -> t a -> m
Use the monoids we defined earlier:
foldMap sum as
foldMap count as
foldMap max as
The mappend
operation distributes through structures like tuple types too.
This lets apply multiple monoids with one traversal.
a2 :: Applicative a => a b -> a c -> a (b, c)
a2 b c = (,) <$> b <*> c
> foldMap (a2 min max) as
(Min 1, Max 456)
This doesn’t let us do Mean very nicely. We need to unpack the pair at the end and calculate the actual
Have an additional Aggregation
class (superclass of Monoid
) which has an
associated type for the result which is extracted from the aggregation.
So we can make a version of foldMap which can finish and unwrap the aggregation:
afoldMap :: (Foldable t, Aggregation a) => (v -> a) -> t v -> AggResult a
afoldMap f vs = AggResult (foldMap f vs)
Combine the aggregation and monoid to apply a filter during the single traversal.
Two monoids for maps:
Replace the values
Insist the values are monoids too and append them.
Compose accessors with the “smart” constructors and apply them to calculate statistics over a stream of records.
Amos Robinson on optimising purely functional loops
Live at UNSW and looking at some optimisation problems. SpecConstr (constructor specialisation) is part of GHC (phase? optimisation?); has some problems, particularly with stream fusion, DPH, etc.
Dot product (pairwise multiple two vectors and sum the results) is a motivating example. We want to write that as:
dotp as bs = fold (+) 0 $ zipWith (*) as bs
But we want to actually execute:
dotp as bs = go 0 0
where
go i acc
| i > V.length as
= acc
| otherwise
= go (i+1) (acc + (as!i * bs!i))
(Assuming that the Ints aren’t boxed, etc.)