# News aggregator

### Call for opinions on whether to use Yesod or Django

Hi,

I'm a self taught Django user since forever, and I've been dabbling in Haskell for the past year or so, having gotten to the point where I can try to get into a bigger project in Haskell. I've read into Yesod, but I've done no actual work except for the occasional tutorial project.

I've no doubt in my mind that I would chose Haskell over Python for almost any kind of project, except for a web project.

However, what I find lacking in the Yesod environment are plugins. There's a huge Django ecosystem, with open-source plugins that do mostly anything from facebook integration to tagging to payment engines to you-name-it.

What are the Haskell community's thoughts about this state of affairs? Are there any Yesod resources I might have overlooked?

submitted by pashadia[link] [14 comments]

### Is there any facility in Haskell for automagically deciding which computations should be eager and which lazy?

I'm not exactly sure how it would work under the hood, but I'm imagining a library that keeps statistics on how often an expression is actually evaluated and eagerly (and in parallel) evaluates the ones with a high enough chance of future use. Kind of like branch prediction in CPUs, except at a higher level. Does any such library or language feature exist? Does the concept even make sense?

submitted by amoralnihilist[link] [17 comments]

### applicative question

### An idea to help Haskell take off

What if we were to make a game in Haskell?

Specifically, a game that has very strong modding support, and a pretty fun concept. Minecraft and the Source engine games have had a lot of success with modding, and a ton of people have had to learn the modding language in order to work on it, and have had the incentive to. If we make this game modded with haskell, and if its successful, that would be an insane boost to the haskell community. It could even have a branching effect, where modders who learnt haskell for this game go and use it to make their own games, for that reason making the game open source would be a very good idea (a guideline for these modders to help conceptualize the structure of a bigger project than their mods.)

What do you think? Its undoubtedly a large project, and coming up with an idea is very tough, but if enough community members got on board i think itd be very doable and very fun to work on.

I also have an idea for a game that could be made. It might be scummy of us and im not sure what the legality of this is but the game Cube World is seriously loved and seriously poipular and only failed because its underdeveloped, and hard to mod. If we went the other way with that i doubt wed have a hard time finding success.

This might also be unrealistic... i know games are massive projects and I dont think the open source community has ever banded together to work on something with almost no purpose besides entertainment.

submitted by fruitbooploops[link] [55 comments]

### HTTP/2 implementation?

### Douglas M. Auclair (geophf): That's totes my Bag!

So, today's question on @1HaskellADay was this:

write a function countOccurences :: [Stirng] -> Map Char Int

(typos faithfully reproduced)

such that

lookup 'l' $ countOccurences "Hello" ~> Just 2

lookup 'q' $ countOccurences "Hello" ~> Nothing

Okay, that can be done easily enough, I suppose, by torquing Map into something that it isn't, so one gets wrapped around the axel of creating a mapping from characters to occurrences.

But why?

First of all, countOccurences maps a String (not a List of Strings) to a Map, and that map is a very specialized kind of map that has existed in the literature for quite a while, and that map is known as the Bag data type, and is also, nowadays, called the MultiSet by people too embarrassed to say the word 'bag' in a sentence, because of their prior drug convictions.

("I got two months for selling a dime bag.")

So they now twist the word 'Set' (a 'collection of unique objects') to mean something that's not a set at all, the 'Multi'Set, which is a 'collection of unique objects, but you can have multiples of these unique objects, so they're not unique at all, so it isn't a set at all, but we need to say the word 'set' because we can't say the word 'bag' because saying the word 'bag' would make us sound plebeian for some reason.'

Yeah, that. 'MultiSet.'

What.

*Ev.*Er.

But I digress.

As always.

So I

*COULD*write the countOccurences as a String -> Map Char Int function, but then: why bother? You can either write tons of algorithmic code that obscures the intent or just simply use the appropriate data type.

I went for the latter.

Now, I

*wuz gonna*do a dependently-typed pair to represent an occurrence...

... notice how countOccurences is so badly misspelled, by the way?

*SOME*body didn't QA-check their problem for the day today, I'm thinking.

... but then I said:

*'eh!'*

I mean:

*WHY*is lookup 'q' $ countOccurences "Hello" ~> Nothing?

*WHY*can't it be that count 'q' for a Bag Char representation of "Hello" be 0? 0 is a valid answer and it keeps everything nice and monoidal without having to lift everything unnecessarily into the monadic domain.

So, yeah. Let's do that, instead.

So, here we go, and in Idris, because that's how I'm rolling these days. The advantages of dependent types have been enumerated elsewhere, so we'll just go with that they're better as an assumption and move on, using them, instead of extolling them, in this post.

**Wrong!**

So, my first attempt at Bag crashed and burned, because I did this:

data Bag : (x : Type) -> Type where

add : Bag x -> x -> Bag x

emptyBag : Bag x

and the compiler was fine with that. Hey, I can declare any type I'd like, so long as the types just stay as types, but as soon as I tried to define these things:

emptyList : List x

emptyList = []

emptyBag = Bag emptyList

add (Bag []) x = Bag [(x, 1)]

add (Bag ((x, y) :: rest)) x = Bag ((x, y + 1) :: rest)

add (Bag ((z, y) :: rest)) x = Bag ((z, y) :: (add rest x))

The compiler looked at me and asked:

*'geophf, what in tarnation are you-ah tryin' to do?'*

And about the only intelligent answer I could muster was:

*'Ummmm... idk.'*

I had gotten too clever for myself by half, trying to reshape a data type you learn in Comp.Sci. 101 as a purely functional type.

**Back to Basics**... (but not BASIC)

So, let's just declare Bag to be what it is and KISS: 'keep it simple, stupid!'

Yes, let's.

data Bag x = Air | Stuffed (x, Nat) (Bag x)

Now, I so totally could've gone with the balanced binary-tree representation instead of the simple and standard linked list, but, you know: 'live and learn!'

With this declaration the emptyBag becomes so trivial as to be unnecessary, and then add is simplicity, itself, too, but add is, either way, so that's not saying much.

add : Eq x => Bag x -> x -> Bag x

add Air x = Stuffed (x, 1) Air

add (Stuffed (z, y) rest) x =

case x == z of

True => Stuffed (x, y + 1) rest

False => Stuffed (z, y) (add rest x)

Now, you see me relying on the case-statement, here. Unhappily.

I'd like my dependent types to say, 'unify x with x (reflexive) for the isomorphic case, and

*don't*unify x with z for the other case.' But we're not there yet, or my coding isn't on par with being there yet, so I forced total coverage bifurcating the result-set into isomorphic and not with a hard-case statement.

Ick. I hate explicit case-statements! Where is really, really, really smart pattern-matching when I need it?

But with add, constructing a Bag becomes easy, and then counting elements of that bag is easy, too (again, with another case-statement, sigh!):

count : Eq x => x -> Bag x -> Nat

count _ Air = 0

count x (Stuffed (z, y) rest) =

case x == z of

True => y

False => count x rest

countOccurences (with one-too-few 'r's in the function name) becomes easy, given the Bag data type:

countOccurences : String -> Bag Char

countOccurences str = co' (unpack str) where

co' [] = Air

co' (char :: rest) = add (co' rest) char

*YAWN!*

*But look at this:*

depth : Bag x -> Nat

depth Air = 0

depth (Stuffed _ rest) = 1 + depth rest

sample : ?bag

sample = countOccurences "The quick, brown fox jumped over the lazy dog."

bag = proof search

When we do a depth sample, we get the not-surprising answer of 29 : Nat

Perhaps this could be made a

*tad*bit more efficient?

Just perhaps.

Well, then, let's do that!

data Bag x = Air | Stuffed (x, Nat) (Bag x) (Bag x)

We make Bag balanced, with the add-function, doing the work of (very simply) branching off new nodes:

add : Ord x => Bag x -> x -> Bag x

add Air x = Stuffed (x, 1) Air Air

add (Stuffed (z, y) less more) x =

case (compare x z) of

LT => Stuffed (z, y) (add less x) more

GT => Stuffed (z, y) less (add more x)

EQ => Stuffed (z, y + 1) less more

Then all the other functions change

*('morph')*to work with a tree, not a list and work with Ord elements, not with (simply) Eq ones.

And so, the redefined depth-function gives a very different result:

depth sample ~> 9 : Nat

Not bad! Not bad! The improved data-structure improves efficiency across the board from O(N) to O(log N).

Hm, perhaps I'll have count return a dependently-typed pair, just as the library function filter does on List types, but not tonight.

Good night, Moon!

### Some thoughts on Isomorphic Types

Some Haskell types are isomorphic, which means we have functions (A and B are the isomorphic types)

a_to_b :: A -> B b_to_a :: B -> Awhich satisfy the laws

a_to_b . b_to_a = id :: A -> A b_to_a . a_to_b = id :: B -> BA simple example would be the types (a,(b,c)) and ((a,b),c) with the functions being

assoc (a,p) = ((a, fst p), snd p) assoc' (p, c) = (fst p, (snd p, c)What this means is that the types are essentially the same with the only difference being their representation. This made me wonder whether it would be a good thing to have the ability to use isomorphic types interchangably on the typelevel. By this I mean that one can declare types as isomorphic by providing the correct functions, the default type to use when one of them is encountered and the typechecker actually treats them as the same type (essentially by inserting the transformation function where needed).

The reason why I thought about this is the following:

Consider a function (<||>) :: (a -> b) -> (c -> d) -> ((a,c) -> (b,d)) which turns two functions into a function on pairs. Since (a,(b,c)) and ((a,b),c) are isomorphic (<||>) behaves like an associative function but one is not able to use it like that, since the types get in the way.

Not only that but since the types ((),a), (a,()) and a are also all isomorphic id| :: () -> () would satisfy the laws of the neutral element of (<||>) but again you can't really use it that way since the types get messed up.

Quick insert: Since I am describing something similar to a monoid and also similar to the category class, I just did a quick google search and it looks like I am describing what makes up a monoidal category. So I guess one thing which would speak for having something like this would be that you have less cumbersome category theoretic things.

So assume Haskell allows you to make declarations like this:

isomorphic a (a,()) to a = (a,()) from (a,()) = a default a -- laws: to . from $ p == id p -- from . to $ a == id aThis means, that whenever the type (a,()) is encountered there is an implicit insertion of from changing the type to a allowing them to be used interchangably.

Would this be more of a good thing or more of a bad thing?

submitted by Pseudoradius[link] [24 comments]

### Obtaining kind of a HsType

### JP Moresmau: BuildWrapper/EclipseFP and GHC 7.8

On the BuildWrapper side, things are more complex. Adapting to API changes wasn't a big deal, but it seems that GHC bugs involving the GHC API, static linking and other unknowns cause some things to break. The solution I've found was to build BuildWrapper with the -dynamic flag. But I couldn't upload this to hackage because Cabal thinks that -dynamic is a debug flag (it starts with d). I've sent a bug fix to Cabal, so in the next release that'll be fixed. So if you're using GHC 7.8 and BuildWrapper, you may want to rebuild the executable with -dynamic (uncomment the relevant line in the cabal file).

Note: BuildWrapper comes with a comprehensive test suite (90 tests covering all aspects). So you can always build the tests and run them to ensure everyting is OK on your system.

Happy Haskell Hacking!

### Network.CGI maintenance - character encodings

### Gabriel Gonzalez: Equational reasoning at scale

Haskell programmers care about the correctness of their software and they specify correctness conditions in the form of equations that their code must satisfy. They can then verify the correctness of these equations using equational reasoning to prove that the abstractions they build are sound. To an outsider this might seem like a futile, academic exercise: proving the correctness of small abstractions is difficult, so what hope do we have to prove larger abstractions correct? This post explains how to do precisely that: scale proofs to large and complex abstractions.

Purely functional programming uses composition to scale programs, meaning that:

- We build small components that we can verify correct in isolation
- We compose smaller components into larger components

If you saw "components" and thought "functions", think again! We can compose things that do not even remotely resemble functions, such as proofs! In fact, Haskell programmers prove large-scale properties exactly the same way we build large-scale programs:

- We build small proofs that we can verify correct in isolation
- We compose smaller proofs into larger proofs

The following sections illustrate in detail how this works in practice, using Monoids as the running example. We will prove the Monoid laws for simple types and work our way up to proving the Monoid laws for much more complex types. Along the way we'll learn how to keep the proof complexity flat as the types grow in size.

MonoidsHaskell's Prelude provides the following Monoid type class:

class Monoid m wheremempty :: m

mappend :: m -> m -> m

-- An infix operator equivalent to `mappend`

(<>) :: Monoid m => m -> m -> m

x <> y = mappend x y

... and all Monoid instances must obey the following two laws:

mempty <> x = x -- Left identityx <> mempty = x -- Right identity

(x <> y) <> z = x <> (y <> z) -- Associativity

For example, Ints form a Monoid:

-- See "Appendix A" for some caveatsinstance Monoid Int where

mempty = 0

mappend = (+)

... and the Monoid laws for Ints are just the laws of addition:

0 + x = xx + 0 = x

(x + y) + z = x + (y + z)

Now we can use (<>) and mempty instead of (+) and 0:

>>> 4 <> 26

>>> 5 <> mempty <> 5

10

This appears useless at first glance. We already have (+) and 0, so why are we using the Monoid operations?

Extending MonoidsWell, what if I want to combine things other than Ints, like pairs of Ints. I want to be able to write code like this:

>>> (1, 2) <> (3, 4)(4, 6)

Well, that seems mildly interesting. Let's try to define a Monoid instance for pairs of Ints:

instance Monoid (Int, Int) wheremempty = (0, 0)

mappend (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)

Now my wish is true and I can "add" binary tuples together using (<>) and mempty:

>>> (1, 2) <> (3, 4)(4, 6)

>>> (1, 2) <> (3, mempty) <> (mempty, 4)

(4, 6)

>>> (1, 2) <> mempty <> (3, 4)

(4, 6)

However, I still haven't proven that this new Monoid instance obeys the Monoid laws. Fortunately, this is a very simple proof.

I'll begin with the first Monoid law, which requires that:

mempty <> x = xWe will begin from the left-hand side of the equation and try to arrive at the right-hand side by substituting equals-for-equals (a.k.a. "equational reasoning"):

-- Left-hand side of the equationmempty <> x

-- x <> y = mappend x y

= mappend mempty x

-- `mempty = (0, 0)`

= mappend (0, 0) x

-- Define: x = (xL, xR), since `x` is a tuple

= mappend (0, 0) (xL, xR)

-- mappend (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)

= (0 + xL, 0 + xR)

-- 0 + x = x

= (xL, xR)

-- x = (xL, xR)

= x

The proof for the second Monoid law is symmetric

-- Left-hand side of the equation= x <> mempty

-- x <> y = mappend x y

= mappend x mempty

-- mempty = (0, 0)

= mappend x (0, 0)

-- Define: x = (xL, xR), since `x` is a tuple

= mappend (xL, xR) (0, 0)

-- mappend (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)

= (xL + 0, xR + 0)

-- x + 0 = x

= (xL, xR)

-- x = (xL, xR)

= x

The third Monoid law requires that (<>) is associative:

(x <> y) <> z = x <> (y <> z)Again I'll begin from the left side of the equation:

-- Left-hand side(x <> y) <> z

-- x <> y = mappend x y

= mappend (mappend x y) z

-- x = (xL, xR)

-- y = (yL, yR)

-- z = (zL, zR)

= mappend (mappend (xL, xR) (yL, yR)) (zL, zR)

-- mappend (x1, y1) (x2 , y2) = (x1 + x2, y1 + y2)

= mappend (xL + yL, xR + yR) (zL, zR)

-- mappend (x1, y1) (x2 , y2) = (x1 + x2, y1 + y2)

= mappend ((xL + yL) + zL, (xR + yR) + zR)

-- (x + y) + z = x + (y + z)

= mappend (xL + (yL + zL), xR + (yR + zR))

-- mappend (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)

= mappend (xL, xR) (yL + zL, yR + zR)

-- mappend (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)

= mappend (xL, xR) (mappend (yL, yR) (zL, zR))

-- x = (xL, xR)

-- y = (yL, yR)

-- z = (zL, zR)

= mappend x (mappend y z)

-- x <> y = mappend x y

= x <> (y <> z)

That completes the proof of the three Monoid laws, but I'm not satisfied with these proofs.

Generalizing proofsI don't like the above proofs because they are disposable, meaning that I cannot reuse them to prove other properties of interest. I'm a programmer, so I loathe busy work and unnecessary repetition, both for code and proofs. I would like to find a way to generalize the above proofs so that I can use them in more places.

We improve proof reuse in the same way that we improve code reuse. To see why, consider the following sort function:

sort :: [Int] -> [Int]This sort function is disposable because it only works on Ints. For example, I cannot use the above function to sort a list of Doubles.

Fortunately, programming languages with generics let us generalize sort by parametrizing sort on the element type of the list:

sort :: Ord a => [a] -> [a]That type says that we can call sort on any list of as, so long as the type a implements the Ord type class (a comparison interface). This works because sort doesn't really care whether or not the elements are Ints; sort only cares if they are comparable.

Similarly, we can make the proof more "generic". If we inspect the proof closely, we will notice that we don't really care whether or not the tuple contains Ints. The only Int-specific properties we use in our proof are:

0 + x = xx + 0 = x

(x + y) + z = x + (y + z)

However, these properties hold true for all Monoids, not just Ints. Therefore, we can generalize our Monoid instance for tuples by parametrizing it on the type of each field of the tuple:

instance (Monoid a, Monoid b) => Monoid (a, b) wheremempty = (mempty, mempty)

mappend (x1, y1) (x2, y2) = (mappend x1 x2, mappend y1 y2)

The above Monoid instance says that we can combine tuples so long as we can combine their individual fields. Our original Monoid instance was just a special case of this instance where both the a and b types are Ints.

Note: The mempty and mappend on the left-hand side of each equation are for tuples. The memptys and mappends on the right-hand side of each equation are for the types a and b. Haskell overloads type class methods like mempty and mappend to work on any type that implements the Monoid type class, and the compiler distinguishes them by their inferred types.

We can similarly generalize our original proofs, too, by just replacing the Int-specific parts with their more general Monoid counterparts.

Here is the generalized proof of the left identity law:

-- Left-hand side of the equationmempty <> x

-- x <> y = mappend x y

= mappend mempty x

-- `mempty = (mempty, mempty)`

= mappend (mempty, mempty) x

-- Define: x = (xL, xR), since `x` is a tuple

= mappend (mempty, mempty) (xL, xR)

-- mappend (x1, y1) (x2, y2) = (mappend x1 x2, mappend y1 y2)

= (mappend mempty xL, mappend mempty xR)

-- Monoid law: mappend mempty x = x

= (xL, xR)

-- x = (xL, xR)

= x

... the right identity law:

-- Left-hand side of the equation= x <> mempty

-- x <> y = mappend x y

= mappend x mempty

-- mempty = (mempty, mempty)

= mappend x (mempty, mempty)

-- Define: x = (xL, xR), since `x` is a tuple

= mappend (xL, xR) (mempty, mempty)

-- mappend (x1, y1) (x2, y2) = (mappend x1 x2, mappend y1 y2)

= (mappend xL mempty, mappend xR mempty)

-- Monoid law: mappend x mempty = x

= (xL, xR)

-- x = (xL, xR)

= x

... and the associativity law:

-- Left-hand side(x <> y) <> z

-- x <> y = mappend x y

= mappend (mappend x y) z

-- x = (xL, xR)

-- y = (yL, yR)

-- z = (zL, zR)

= mappend (mappend (xL, xR) (yL, yR)) (zL, zR)

-- mappend (x1, y1) (x2 , y2) = (mappend x1 x2, mappend y1 y2)

= mappend (mappend xL yL, mappend xR yR) (zL, zR)

-- mappend (x1, y1) (x2 , y2) = (mappend x1 x2, mappend y1 y2)

= (mappend (mappend xL yL) zL, mappend (mappend xR yR) zR)

-- Monoid law: mappend (mappend x y) z = mappend x (mappend y z)

= (mappend xL (mappend yL zL), mappend xR (mappend yR zR))

-- mappend (x1, y1) (x2, y2) = (mappend x1 x2, mappend y1 y2)

= mappend (xL, xR) (mappend yL zL, mappend yR zR)

-- mappend (x1, y1) (x2, y2) = (mappend x1 x2, mappend y1 y2)

= mappend (xL, xR) (mappend (yL, yR) (zL, zR))

-- x = (xL, xR)

-- y = (yL, yR)

-- z = (zL, zR)

= mappend x (mappend y z)

-- x <> y = mappend x y

= x <> (y <> z)

This more general Monoid instance lets us stick any Monoids inside the tuple fields and we can still combine the tuples. For example, lists form a Monoid:

-- Exercise: Prove the monoid laws for listsinstance Monoid [a] where

mempty = []

mappend = (++)

... so we can stick lists inside the right field of each tuple and still combine them:

>>> (1, [2, 3]) <> (4, [5, 6])(5, [2, 3, 5, 6])

>>> (1, [2, 3]) <> (4, mempty) <> (mempty, [5, 6])

(5, [2, 3, 5, 6])

>>> (1, [2, 3]) <> mempty <> (4, [5, 6])

(5, [2, 3, 5, 6])

Why, we can even stick yet another tuple inside the right field and still combine them:

>>> (1, (2, 3)) <> (4, (5, 6))(5, (7, 9))

We can try even more exotic permutations and everything still "just works":

>>> ((1,[2, 3]), ([4, 5], 6)) <> ((7, [8, 9]), ([10, 11), 12)((8, [2, 3, 8, 9]), ([4, 5, 10, 11], 18))

This is our first example of a "scalable proof". We began from three primitive building blocks:

- Int is a Monoid
- [a] is a Monoid
- (a, b) is a Monoid if a is a Monoid and b is a Monoid

... and we connected those three building blocks to assemble a variety of new Monoid instances. No matter how many tuples we nest the result is still a Monoid and obeys the Monoid laws. We don't need to re-prove the Monoid laws every time we assemble a new permutation of these building blocks.

However, these building blocks are still pretty limited. What other useful things can we combine to build new Monoids?

IOWe're so used to thinking of Monoids as data, so let's define a new Monoid instance for something entirely un-data-like:

-- See "Appendix A" for some caveatsinstance Monoid b => Monoid (IO b) where

mempty = return mempty

mappend io1 io2 = do

a1 <- io1

a2 <- io2

return (mappend a1 a2)

The above instance says: "If a is a Monoid, then an IO action that returns an a is also a Monoid". Let's test this using the getLine function from the Prelude:

-- Read one line of input from stdingetLine :: IO String

String is a Monoid, since a String is just a list of characters, so we should be able to mappend multiple getLine statements together. Let's see what happens:

>>> getLine -- Reads one line of inputHello<Enter>

"Hello"

>>> getLine <> getLine

ABC<Enter>

DEF<Enter>

"ABCDEF"

>>> getLine <> getLine <> getLine

1<Enter>

23<Enter>

456<Enter>

"123456"

Neat! When we combine multiple commands we combine their effects and their results.

Of course, we don't have to limit ourselves to reading strings. We can use readLn from the Prelude to read in anything that implements the Read type class:

-- Parse a `Read`able value from one line of stdinreadLn :: Read a => IO a

All we have to do is tell the compiler which type a we intend to Read by providing a type signature:

>>> readLn :: IO (Int, Int)(1, 2)<Enter>

(1 ,2)

>>> readLn <> readLn :: IO (Int, Int)

(1,2)<Enter>

(3,4)<Enter>

(4,6)

>>> readLn <> readLn <> readLn :: IO (Int, Int)

(1,2)<Enter>

(3,4)<Enter>

(5,6)<Enter>

(9,12)

This works because:

- Int is a Monoid
- Therefore, (Int, Int) is a Monoid
- Therefore, IO (Int, Int) is a Monoid

Or let's flip things around and nest IO actions inside of a tuple:

>>> let ios = (getLine, readLn) :: (IO String, IO (Int, Int))>>> let (getLines, readLns) = ios <> ios <> ios

>>> getLines

1<Enter>

23<Enter>

456<Enter>

123456

>>> readLns

(1,2)<Enter>

(3,4)<Enter>

(5,6)<Enter>

(9,12)

We can very easily reason that the type (IO String, IO (Int, Int)) obeys the Monoid laws because:

- String is a Monoid
- If String is a Monoid then IO String is also a Monoid
- Int is a Monoid
- If Int is a Monoid, then (Int, Int) is also a `Monoid
- If (Int, Int) is a Monoid, then IO (Int, Int) is also a Monoid
- If IO String is a Monoid and IO (Int, Int) is a Monoid, then (IO String, IO (Int, Int)) is also a Monoid

However, we don't really have to reason about this at all. The compiler will automatically assemble the correct Monoid instance for us. The only thing we need to verify is that the primitive Monoid instances obey the Monoid laws, and then we can trust that any larger Monoid instance the compiler derives will also obey the Monoid laws.

The Unit MonoidHaskell Prelude also provides the putStrLn function, which echoes a String to standard output with a newline:

putStrLn :: String -> IO ()Is putStrLn combinable? There's only one way to find out!

>>> putStrLn "Hello" <> putStrLn "World"Hello

World

Interesting, but why does that work? Well, let's look at the types of the commands we are combining:

putStrLn "Hello" :: IO ()putStrLn "World" :: IO ()

Well, we said that IO b is a Monoid if b is a Monoid, and b in this case is () (pronounced "unit"), which you can think of as an "empty tuple". Therefore, () must form a Monoid of some sort, and if we dig into Data.Monoid, we will discover the following Monoid instance:

-- Exercise: Prove the monoid laws for `()`instance Monoid () where

mempty = ()

mappend () () = ()

This says that empty tuples form a trivial Monoid, since there's only one possible value (ignoring bottom) for an empty tuple: (). Therefore, we can derive that IO () is a Monoid because () is a Monoid.

FunctionsAlright, so we can combine putStrLn "Hello" with putStrLn "World", but can we combine naked putStrLn functions?

>>> (putStrLn <> putStrLn) "Hello"Hello

Hello

Woah, how does that work?

We never wrote a Monoid instance for the type String -> IO (), yet somehow the compiler magically accepted the above code and produced a sensible result.

This works because of the following Monoid instance for functions:

instance Monoid b => Monoid (a -> b) wheremempty = \_ -> mempty

mappend f g = \a -> mappend (f a) (g a)

This says: "If b is a Monoid, then any function that returns a b is also a Monoid".

The compiler then deduced that:

- () is a Monoid
- If () is a Monoid, then IO () is also a Monoid
- If IO () is a Monoid then String -> IO () is also a Monoid

The compiler is a trusted friend, deducing Monoid instances we never knew existed.

Monoid pluginsNow we have enough building blocks to assemble a non-trivial example. Let's build a key logger with a Monoid-based plugin system.

The central scaffold of our program is a simple main loop that echoes characters from standard input to standard output:

main = dohSetEcho stdin False

forever $ do

c <- getChar

putChar c

However, we would like to intercept key strokes for nefarious purposes, so we will slightly modify this program to install a handler at the beginning of the program that we will invoke on every incoming character:

install :: IO (Char -> IO ())install = ???

main = do

hSetEcho stdin False

handleChar <- install

forever $ do

c <- getChar

handleChar c

putChar c

Notice that the type of install is exactly the correct type to be a Monoid:

- () is a Monoid
- Therefore, IO () is also a Monoid
- Therefore Char -> IO () is also a Monoid
- Therefore IO (Char -> IO ()) is also a Monoid

Therefore, we can combine key logging plugins together using Monoid operations. Here is one such example:

type Plugin = IO (Char -> IO ())logTo :: FilePath -> Plugin

logTo filePath = do

handle <- openFile filePath WriteMode

return (hPutChar handle)

main = do

hSetEcho stdin False

handleChar <- logTo "file1.txt" <> logTo "file2.txt"

forever $ do

c <- getChar

handleChar c

putChar c

Now, every key stroke will be recorded to both file1.txt and file2.txt. Let's confirm that this works as expected:

$ ./loggerTest<Enter>

ABC<Enter>

42<Enter>

<Ctrl-C>

$ cat file1.txt

Test

ABC

42

$ cat file2.txt

Test

ABC

42

Try writing your own Plugins and mixing them in with (<>) to see what happens. "Appendix C" contains the complete code for this section so you can experiment with your own Plugins.

ApplicativesNotice that I never actually proved the Monoid laws for the following two Monoid instances:

instance Monoid b => Monoid (a -> b) wheremempty = \_ -> mempty

mappend f g = \a -> mappend (f a) (g a)

instance Monoid a => Monoid (IO a) where

mempty = return mempty

mappend io1 io2 = do

a1 <- io1

a2 <- io2

return (mappend a1 a2)

The reason why is that they are both special cases of a more general pattern. We can detect the pattern if we rewrite both of them to use the pure and liftA2 functions from Control.Applicative:

import Control.Applicative (pure, liftA2)instance Monoid b => Monoid (a -> b) where

mempty = pure mempty

mappend = liftA2 mappend

instance Monoid b => Monoid (IO b) where

mempty = pure mempty

mappend = liftA2 mappend

This works because both IO and functions implement the following Applicative interface:

class Functor f => Applicative f wherepure :: a -> f a

(<*>) :: f (a -> b) -> f a -> f b

-- Lift a binary function over the functor `f`

liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

liftA2 f x y = (pure f <*> x) <*> y

... and all Applicative instances must obey several Applicative laws:

pure id <*> v = v((pure (.) <*> u) <*> v) <*> w = u <*> (v <*> w)

pure f <*> pure x = pure (f x)

u <*> pure x = pure (\f -> f y) <*> u

These laws may seem a bit adhoc, but this paper explains that you can reorganize the Applicative class to this equivalent type class:

class Functor f => Monoidal f whereunit :: f ()

(#) :: f a -> f b -> f (a, b)

Then the corresponding laws become much more symmetric:

fmap snd (unit # x) = x -- Left identityfmap fst (x # unit) = x -- Right identity

fmap assoc ((x # y) # z) = x # (y # z) -- Associativity

where

assoc ((a, b), c) = (a, (b, c))

fmap (f *** g) (x # y) = fmap f x # fmap g y -- Naturality

where

(f *** g) (a, b) = (f a, g b)

I personally prefer the Monoidal formulation, but you go to war with the army you have, so we will use the Applicative type class for this post.

All Applicatives possess a very powerful property: they can all automatically lift Monoid operations using the following instance:

instance (Applicative f, Monoid b) => Monoid (f b) wheremempty = pure mempty

mappend = liftA2 mappend

This says: "If f is an Applicative and b is a Monoid, then f b is also a Monoid." In other words, we can automatically extend any existing Monoid with some new feature f and get back a new Monoid.

Note: The above instance is bad Haskell because it overlaps with other type class instances. In practice we have to duplicate the above code once for each Applicative. Also, for some Applicatives we may want a different Monoid instance.

We can prove that the above instance obeys the Monoid laws without knowing anything about f and b, other than the fact that f obeys the Applicative laws and b obeys the Applicative laws. These proofs are a little long, so I've included them in Appendix B.

Both IO and functions implement the Applicative type class:

instance Applicative IO wherepure = return

iof <*> iox = do

f <- iof

x <- iox

return (f x)

instance Applicative ((->) a) where

pure x = \_ -> x

kf <*> kx = \a ->

let f = kf a

x = kx a

in f x

This means that we can kill two birds with one stone. Every time we prove the Applicative laws for some functor F:

instance Applicative F where ...... we automatically prove that the following Monoid instance is correct for free:

instance Monoid b => Monoid (F b) wheremempty = pure mempty

mappend = liftA2 mappend

In the interest of brevity, I will skip the proofs of the Applicative laws, but I may cover them in a subsequent post.

The beauty of Applicative Functors is that every new Applicative instance we discover adds a new building block to our Monoid toolbox, and Haskell programmers have already discovered lots of Applicative Functors.

Revisiting tuplesOne of the very first Monoid instances we wrote was:

instance (Monoid a, Monoid b) => Monoid (a, b) wheremempty = (mempty, mempty)

mappend (x1, y1) (x2, y2) = (mappend x1 x2, mappend y1 y2)

Check this out:

instance (Monoid a, Monoid b) => Monoid (a, b) wheremempty = pure mempty

mappend = liftA2 mappend

This Monoid instance is yet another special case of the Applicative pattern we just covered!

This works because of the following Applicative instance in Control.Applicative:

instance Monoid a => Applicative ((,) a) wherepure b = (mempty, b)

(a1, f) <*> (a2, x) = (mappend a1 a2, f x)

This instance obeys the Applicative laws (proof omitted), so our Monoid instance for tuples is automatically correct, too.

Composing applicativesIn the very first section I wrote:

Haskell programmers prove large-scale properties exactly the same way we build large-scale programs:

- We build small proofs that we can verify correct in isolation
- We compose smaller proofs into larger proofs

I don't like to use the word compose lightly. In the context of category theory, compose has a very rigorous meaning, indicating composition of morphisms in some category. This final section will show that we can actually compose Monoid proofs in a very rigorous sense of the word.

We can define a category of Monoid proofs:

- Objects are types and their associated Monoid proofs
- Morphisms are Applicative Functors
- The identity morphism is the Identity applicative
- The composition operation is composition of Applicative Functors
- The category laws are isomorphisms instead of equalities

So in our Plugin example, we began on the proof that () was a Monoid and then composed three Applicative morphisms to prove that Plugin was a Monoid. I will use the following diagram to illustrate this:

+-----------------------+| |

| Legend: * = Object |

| |

| v |

| | = Morphism |

| v |

| |

+-----------------------+

* `()` is a `Monoid`

v

| IO

v

* `IO ()` is a `Monoid`

v

| ((->) String)

v

* `String -> IO ()` is a `Monoid`

v

| IO

v

* `IO (String -> IO ())` (i.e. `Plugin`) is a `Monoid`

Therefore, we were literally composing proofs together.

ConclusionYou can equationally reason at scale by decomposing larger proofs into smaller reusable proofs, the same way we decompose programs into smaller and more reusable components. There is no limit to how many proofs you can compose together, and therefore there is no limit to how complex of a program you can tame using equational reasoning.

This post only gave one example of composing proofs within Haskell. The more you learn the language, the more examples of composable proofs you will encounter. Another common example is automatically deriving Monad proofs by composing monad transformers.

As you learn Haskell, you will discover that the hard part is not proving things. Rather, the challenge is learning how to decompose proofs into smaller proofs and you can cultivate this skill by studying category theory and abstract algebra. These mathematical disciplines teach you how to extract common and reusable proofs and patterns from what appears to be disposable and idiosyncratic code.

Appendix A - Missing Monoid instancesThese Monoid instance from this post do not actually appear in the Haskell standard library:

instance Monoid b => Monoid (IO b)instance Monoid Int

The first instance was recently proposed here on the Glasgow Haskell Users mailing list. However, in the short term you can work around it by writing your own Monoid instances by hand just by inserting a sufficient number of pures and liftA2s.

For example, suppose we wanted to provide a Monoid instance for Plugin. We would just newtype Plugin and write:

newtype Plugin = Plugin { install :: IO (String -> IO ()) }instance Monoid Plugin where

mempty = Plugin (pure (pure (pure mempty)))

mappend (Plugin p1) (Plugin p2) =

Plugin (liftA2 (liftA2 (liftA2 mappend)) p1 p2)

This is what the compiler would have derived by hand.

Alternatively, you could define an orphan Monoid instance for IO, but this is generally frowned upon.

There is no default Monoid instance for Int because there are actually two possible instances to choose from:

-- Alternative #1instance Monoid Int where

mempty = 0

mappend = (+)

-- Alternative #2

instance Monoid Int where

mempty = 1

mappend = (*)

So instead, Data.Monoid sidesteps the issue by providing two newtypes to distinguish which instance we prefer:

newtype Sum a = Sum { getSum :: a }instance Num a => Monoid (Sum a)

newtype Product a = Product { getProduct :: a}

instance Num a => Monoid (Product a)

An even better solution is to use a semiring, which allows two Monoid instances to coexist for the same type. You can think of Haskell's Num class as an approximation of the semiring class:

class Num a wherefromInteger :: Integer -> a

(+) :: a -> a -> a

(*) :: a -> a -> a

-- ... and other operations unrelated to semirings

Note that we can also lift the Num class over the Applicative class, exactly the same way we lifted the Monoid class. Here's the code:

instance (Applicative f, Num a) => Num (f a) wherefromInteger n = pure (fromInteger n)

(+) = liftA2 (+)

(*) = liftA2 (*)

(-) = liftA2 (-)

negate = fmap negate

abs = fmap abs

signum = fmap signum

This lifting guarantees that if a obeys the semiring laws then so will f a. Of course, you will have to specialize the above instance to every concrete Applicative because otherwise you will get overlapping instances.

Appendix BThese are the proofs to establish that the following Monoid instance obeys the Monoid laws:

instance (Applicative f, Monoid b) => Monoid (f b) wheremempty = pure mempty

mappend = liftA2 mappend

... meaning that if f obeys the Applicative laws and b obeys the Monoid laws, then f b also obeys the Monoid laws.

Proof of the left identity law:

mempty <> x-- x <> y = mappend x y

= mappend mempty x

-- mappend = liftA2 mappend

= liftA2 mappend mempty x

-- mempty = pure mempty

= liftA2 mappend (pure mempty) x

-- liftA2 f x y = (pure f <*> x) <*> y

= (pure mappend <*> pure mempty) <*> x

-- Applicative law: pure f <*> pure x = pure (f x)

= pure (mappend mempty) <*> x

-- Eta conversion

= pure (\a -> mappend mempty a) <*> x

-- mappend mempty x = x

= pure (\a -> a) <*> x

-- id = \x -> x

= pure id <*> x

-- Applicative law: pure id <*> v = v

= x

Proof of the right identity law:

x <> mempty = x-- x <> y = mappend x y

= mappend x mempty

-- mappend = liftA2 mappend

= liftA2 mappend x mempty

-- mempty = pure mempty

= liftA2 mappend x (pure mempty)

-- liftA2 f x y = (pure f <*> x) <*> y

= (pure mappend <*> x) <*> pure mempty

-- Applicative law: u <*> pure y = pure (\f -> f y) <*> u

= pure (\f -> f mempty) <*> (pure mappend <*> x)

-- Applicative law: ((pure (.) <*> u) <*> v) <*> w = u <*> (v <*> w)

= ((pure (.) <*> pure (\f -> f mempty)) <*> pure mappend) <*> x

-- Applicative law: pure f <*> pure x = pure (f x)

= (pure ((.) (\f -> f mempty)) <*> pure mappend) <*> x

-- Applicative law : pure f <*> pure x = pure (f x)

= pure ((.) (\f -> f mempty) mappend) <*> x

-- `(.) f g` is just prefix notation for `f . g`

= pure ((\f -> f mempty) . mappend) <*> x

-- f . g = \x -> f (g x)

= pure (\x -> (\f -> f mempty) (mappend x)) <*> x

-- Apply the lambda

= pure (\x -> mappend x mempty) <*> x

-- Monoid law: mappend x mempty = x

= pure (\x -> x) <*> x

-- id = \x -> x

= pure id <*> x

-- Applicative law: pure id <*> v = v

= x

Proof of the associativity law:

(x <> y) <> z-- x <> y = mappend x y

= mappend (mappend x y) z

-- mappend = liftA2 mappend

= liftA2 mappend (liftA2 mappend x y) z

-- liftA2 f x y = (pure f <*> x) <*> y

= (pure mappend <*> ((pure mappend <*> x) <*> y)) <*> z

-- Applicative law: ((pure (.) <*> u) <*> v) <*> w = u <*> (v <*> w)

= (((pure (.) <*> pure mappend) <*> (pure mappend <*> x)) <*> y) <*> z

-- Applicative law: pure f <*> pure x = pure (f x)

= ((pure f <*> (pure mappend <*> x)) <*> y) <*> z

where

f = (.) mappend

-- Applicative law: ((pure (.) <*> u) <*> v) <*> w = u <*> (v <*> w)

= ((((pure (.) <*> pure f) <*> pure mappend) <*> x) <*> y) <*> z

where

f = (.) mappend

-- Applicative law: pure f <*> pure x = pure (f x)

= (((pure f <*> pure mappend) <*> x) <*> y) <*> z

where

f = (.) ((.) mappend)

-- Applicative law: pure f <*> pure x = pure (f x)

= ((pure f <*> x) <*> y) <*> z

where

f = (.) ((.) mappend) mappend

-- (.) f g = f . g

= ((pure f <*> x) <*> y) <*> z

where

f = ((.) mappend) . mappend

-- Eta conversion

= ((pure f <*> x) <*> y) <*> z

where

f x = (((.) mappend) . mappend) x

-- (f . g) x = f (g x)

= ((pure f <*> x) <*> y) <*> z

where

f x = (.) mappend (mappend x)

-- (.) f g = f . g

= ((pure f <*> x) <*> y) <*> z

where

f x = mappend . (mappend x)

-- Eta conversion

= ((pure f <*> x) <*> y) <*> z

where

f x y = (mappend . (mappend x)) y

-- (f . g) x = f (g x)

= ((pure f <*> x) <*> y) <*> z

where

f x y = mappend (mappend x y)

-- Eta conversion

= ((pure f <*> x) <*> y) <*> z

where

f x y z = mappend (mappend x y) z

-- Monoid law: mappend (mappend x y) z = mappend x (mappend y z)

= ((pure f <*> x) <*> y) <*> z

where

f x y z = mappend x (mappend y z)

-- (f . g) x = f (g x)

= ((pure f <*> x) <*> y) <*> z

where

f x y z = (mappend x . mappend y) z

-- Eta conversion

= ((pure f <*> x) <*> y) <*> z

where

f x y = mappend x . mappend y

-- (.) f g = f . g

= ((pure f <*> x) <*> y) <*> z

where

f x y = (.) (mappend x) (mappend y)

-- (f . g) x = f

= ((pure f <*> x) <*> y) <*> z

where

f x y = (((.) . mappend) x) (mappend y)

-- (f . g) x = f (g x)

= ((pure f <*> x) <*> y) <*> z

where

f x y = ((((.) . mappend) x) . mappend) y

-- Eta conversion

= ((pure f <*> x) <*> y) <*> z

where

f x = (((.) . mappend) x) . mappend

-- (.) f g = f . g

= ((pure f <*> x) <*> y) <*> z

where

f x = (.) (((.) . mappend) x) mappend

-- Lambda abstraction

= ((pure f <*> x) <*> y) <*> z

where

f x = (\k -> k mappend) ((.) (((.) . mappend) x))

-- (f . g) x = f (g x)

= ((pure f <*> x) <*> y) <*> z

where

f x = (\k -> k mappend) (((.) . ((.) . mappend)) x)

-- Eta conversion

= ((pure f <*> x) <*> y) <*> z

where

f = (\k -> k mappend) . ((.) . ((.) . mappend))

-- (.) f g = f . g

= ((pure f <*> x) <*> y) <*> z

where

f = (.) (\k -> k mappend) ((.) . ((.) . mappend))

-- Applicative law: pure f <*> pure x = pure (f x)

= (((pure g <*> pure f) <*> x) <*> y) <*> z

where

g = (.) (\k -> k mappend)

f = (.) . ((.) . mappend)

-- Applicative law: pure f <*> pure x = pure (f x)

= ((((pure (.) <*> pure (\k -> k mappend)) <*> pure f) <*> x) <*> y) <*> z

where

f = (.) . ((.) . mappend)

-- Applicative law: ((pure (.) <*> u) <*> v) <*> w = u <*> (v <*> w)

= ((pure (\k -> k mappend) <*> (pure f <*> x)) <*> y) <*> z

where

f = (.) . ((.) . mappend)

-- u <*> pure y = pure (\k -> k y) <*> u

= (((pure f <*> x) <*> pure mappend) <*> y) <*> z

where

f = (.) . ((.) . mappend)

-- (.) f g = f . g

= (((pure f <*> x) <*> pure mappend) <*> y) <*> z

where

f = (.) (.) ((.) . mappend)

-- Applicative law: pure f <*> pure x = pure (f x)

= ((((pure g <*> pure f) <*> x) <*> pure mappend) <*> y) <*> z

where

g = (.) (.)

f = (.) . mappend

-- Applicative law: pure f <*> pure x = pure (f x)

= (((((pure (.) <*> pure (.)) <*> pure f) <*> x) <*> pure mappend) <*> y) <*> z

where

f = (.) . mappend

-- Applicative law: ((pure (.) <*> u) <*> v) <*> w = u <*> (v <*> w)

= (((pure (.) <*> (pure f <*> x)) <*> pure mappend) <*> y) <*> z

where

f = (.) . mappend

-- Applicative law: ((pure (.) <*> u) <*> v) <*> w = u <*> (v <*> w)

= ((pure f <*> x) <*> (pure mappend <*> y)) <*> z

where

f = (.) . mappend

-- (.) f g = f . g

= ((pure f <*> x) <*> (pure mappend <*> y)) <*> z

where

f = (.) (.) mappend

-- Applicative law: pure f <*> pure x = pure (f x)

= (((pure f <*> pure mappend) <*> x) <*> (pure mappend <*> y)) <*> z

where

f = (.) (.)

-- Applicative law: pure f <*> pure x = pure (f x)

= ((((pure (.) <*> pure (.)) <*> pure mappend) <*> x) <*> (pure mappend <*> y)) <*> z

-- Applicative law: ((pure (.) <*> u) <*> v) <*> w = u <*> (v <*> w)

= ((pure (.) <*> (pure mappend <*> x)) <*> (pure mappend <*> y)) <*> z

-- Applicative law: ((pure (.) <*> u) <*> v) <*> w = u <*> (v <*> w)

= (pure mappend <*> x) <*> ((pure mappend <*> y) <*> z)

-- liftA2 f x y = (pure f <*> x) <*> y

= liftA2 mappend x (liftA2 mappend y z)

-- mappend = liftA2 mappend

= mappend x (mappend y z)

-- x <> y = mappend x y

= x <> (y <> z)Appendix C: Monoid key logging

Here is the complete program for a key logger with a Monoid-based plugin system:

import Control.Applicative (pure, liftA2)import Control.Monad (forever)

import Data.Monoid

import System.IO

instance Monoid b => Monoid (IO b) where

mempty = pure mempty

mappend = liftA2 mappend

type Plugin = IO (Char -> IO ())

logTo :: FilePath -> Plugin

logTo filePath = do

handle <- openFile filePath WriteMode

return (hPutChar handle)

main = do

hSetEcho stdin False

handleChar <- logTo "file1.txt" <> logTo "file2.txt"

forever $ do

c <- getChar

handleChar c

putChar c

### This just in, from my local GHC/Cabal checkout... (re: Cabal Hell)

Transcript: http://lpaste.net/107785

Commentary: Here's what the test is doing:

- It builds and installs a package p-1.0, which contains "module P where p = 1"
- It builds and installs a package q, depending on p, which contains "module Q where import P; q = p + 10"
- It builds and installs a package p-1.1, which contains "module P where p = 1"
- It
**non-destructively reinstalls**package q, but this time building against p-1.1 instead of p-1.0 - It builds an executable r (building against p-1.1 and q-1.0)
- With the same package database, we specify constraint that p==1.0, and rebuild executable r, which prints the value of q (building against p-1.0 and the other instance of q-1.0)
- It tests the two executables to make sure they behave as expected

There are still a minor pile of kinks to work out (in particular, only cabal configure understands this; cabal install's dependency solver also has to be clued in), but from here, it should be possible to do away with one of the major use-cases for Cabal sandboxes and put them all in the same package database, and support a 'cabal upgrade' command.

P.S. It's also possible to link q-1.0(p-1.0) and q-1.0(p-1.1) together in the same program, although I don't think this feature will be too useful without Backpack-like holes.

submitted by ezyang[link] [13 comments]