haskoin/haskoin — pull request #130 by plaprade (2014-12-14 00:38:22+00:00)
Title: Adding distinct types for compressed and uncompressed keys

I use an internal phantom type (PubKeyI c) with hidden data constructors. The phantom parameter can be Generic, Compressed or Uncompressed. By default, Generic is used and the compression is tracked as data inside the type. However, you can use Compressed or Uncompressed to have distinct types for each case.

Type aliases are provided for convenience:

```haskell
type PubKey = PubKeyI Generic
type PubKeyC = PubKeyI Compressed
type PubKeyU = PubKeyI Uncompressed
```

The same pattern is used for private keys.

The advantage of this method is to expose specific compressed and uncompressed types where needed (ex: only compressed keys are allowed in extended bip32 keys) while retaining the generic behavior everywhere else where compression doesn't matter and where you need homogeneous lists of keys that can be both compressed or uncompressed. The solution remains simple and non-invasive: there are no phantom parameters leaking all over the library. Using phantom types also simplifies the library as high-level functions that apply to any key type can be easily defined without having to create specialized versions for each compression type.