Roman Cheplyaka


Extensible effects: abstracting from the transformer

December 6, 2014

In Type-based lift, we saw a way to lift monadic actions automatically to the right layer of a multilayer monad transformer stack, based only on the types involved.

Namely, we defined a closed type family

type family Find (t :: (* -> *) -> (* -> *)) (m :: * -> *) :: Nat where
  Find t (t m) = Zero
  Find t (p m) = Suc (Find t m)

that computes the type-level index of the layer t in the stack m. Such an index can then be used to construct an appropriate lifting function of type t n a -> m a.

This works well as a shortcut, so instead of writing lift, or lift . lift, or lift . lift . lift, we can write magicLift, and let it figure out how far to lift.

However, the lifting is expressed in terms of specific transformers, and not the effects they can handle. For example, a stateful computation may target the strict State monad or the lazy one, but not both, because they are implemented by distinct types.

Let’s fix this!

Continue reading…

Rebalancing Open Source Portfolio

November 1, 2014

Being an open source developer means being an investor. I invest my time in creating, contributing to, and maintaining projects. As an investor, I occasionally need to re-evaluate my portfolio and decide whether it is optimal.

The result of a recent such re-evaluation is that I’ve decided to stop my active involvement in the haskell-suite family of projects.

Continue reading…

Dependent Haskell

September 5, 2014

Emulating dependent types (and, more generally, advanced type-level programming) has been a hot topic in the Haskell community recently. Some incredible work has been done in this direction: GADTs, open and closed type families, singletons, etc. The plan is to copy even more features to the type level, like type classes and GADTs, and simplify the promotion of value-level functions.

On the other hand, there’s a good deal of scepticism around this idea. «If you want to program like in Agda, why don’t you program in Agda?»

Continue reading…

Beware of bracket

July 30, 2014

Many Haskellers know and love the bracket function:

bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c

In our volatile world bracket provides a safe haven of certainty: the resource will be released, no matter what. However, there’s a catch. (Nice pun, huh?)

This article describes two observations about bracket that are useful to keep in mind when writing concurrent Haskell code.

Continue reading…

Type-based lift

July 15, 2014

In mtl, the ask method of the MonadReader class will automatically «lift» itself to the topmost ReaderT layer in the stack, which is very convenient, but only works as long as the topmost layer is the one you need. If you have multiple ReaderTs in the stack, you often have to insert manual lifts.

Previously I described why a smarter automatic lifting mechanism is needed to build truly reusable pieces of monadic code without too much boilerplate.

In this article I show two ways to achieve a type-based lift (that is, a lift which takes into account the r of ReaderT r), one relying on IncoherentInstances, the other — on closed type families.

Continue reading…

How to run SQL actions in persistent

July 7, 2014

When I started writing an application that used persistent to interact with a MySQL database, I decided to put the whole application inside one big SqlPersistM action, and run it once inside main. (To make it clear, this is not a Yesod application; I simply use persistent as a standalone library.)

However, as I learned more about persistent and how it worked, it became clear that this was the wrong way to use persistent. Here’s why.

Continue reading…

Two failed attempts at extensible effects

June 14, 2014

After I had published The problem with mtl, many people wondered what my proposed solution was. If you, like them, are impatient to find out, feel free to peek at the slides from my kievfprog talk, or directly at the code on github.

Still, I’ll continue this series at my own pace. Today we’ll look at two failed solutions to the problem described in the previous article.

Continue reading…

The problem with mtl

June 11, 2014

This article starts a series in which I am going to publish my thoughts on and experience with different «extensible effects» approaches. This one in particular will explain the problem with the classic mtl approach that motivates us to explore extensible effects in the first place.

Continue reading…

Avoid equational function definitions

May 9, 2014

One of the first things that Haskell beginners usually notice is that Haskell has this somewhat unusual but attractive way of defining functions case-by-case:

foldr f z []     = z 
foldr f z (x:xs) = f x (foldr f z xs) 

It looks fun and math-y. The other way to do pattern matching, case expressions, is much less advertized, probably because case invokes associations with dirty old imperative programming. Here’s how the same function could be defined using case:

foldr f z l =
  case l of
    []   -> z 
    x:xs -> f x (foldr f z xs) 

However, there are plenty of reasons to prefer case to multiple function definition clauses.

Continue reading…

Lens is unidiomatic Haskell

April 24, 2014

Edward Kmett writes:

Ironically if I had to say anything from the traffic in my inbox and on #haskell about it, it is mostly the old guard who gets disgruntled by lens.

So let me try and explain why that is. I’ll go ahead and say this: lens is unidiomatic Haskell.

By which I mean that lens isn’t like any other library that we normally use. It doesn’t follow the conventions of Haskell APIs, on which I elaborate below.

Continue reading…

Setting up Samsung Wireless Printer on Linux

April 21, 2014

Here’s a complete guide for setting up a wireless Samsung printer on Linux, where by “setting up” I mean making it connect to your wireless network.

It worked for me with Samsung ML-2165W on Debian GNU/Linux «jessie», but should work for other models and distributions, too.

Continue reading…

JSON validation combinators

April 20, 2014

At Signal Vine we have a JSON-based language for describing text messaging campaigns. We may design a better surface syntax for this language in the future, but the current one gets the job done and there are certain existing systems that depend on it.

Anyway, the problem with this language is that it is too easy to make mistakes — including errors in JSON syntax, structural errors (plugging an array where an object is expected), or name errors (making a typo in a field name).

So the first thing I did was write a validator for our JSON format.

Continue reading…

Find out the type of an expression/function with typed holes

March 13, 2014

An often asked Haskell question is how to find out a type of a locally defined function or expression.

The classic solutions are to specify the wrong type and read the error message, or get help from a tool like hdevtools.

Here’s a new one: use the typed holes feature of GHC 7.8+.

Continue reading…

Happy, Alex, and GHC 7.8

March 8, 2014

As we approach the 7.8 release of GHC, more and more people are running into problems with packages that use Alex and/or Happy for parsing.

Continue reading…

cabal sandbox tips

March 5, 2014

In case you missed it, starting from version 1.18 cabal-install has awesome sandboxing capabilities. Here I share a couple of tricks that will make your sandboxing experience even better.

Continue reading…

tasty-0.8 and other news

March 3, 2014

I’m glad to announce the 0.8 release of tasty, a modern Haskell testing framework.

Continue reading…

My Haskell will

February 8, 2014

I hate it when maintainers become unreachable. At the same time, I’m not immune to that myself (if nothing else, I could be hit by a bus tomorrow).

So I contacted a few people with a request to become backup maintainers (BM) for some of my more popular Haskell packages, and they kindly agreed.

Continue reading…