It was well into my Haskell career before I was able to create type classes to solve problems regularly.\n\nIn retrospect, I did not have a good grasp of how instance selection worked. I didn’t understand when I was going down a path that would result in overlapping instances or when I was in the clear.\n\n### Simple Overlap\n\nI’ll often see Haskellers write code like I used to:\n\nclass Combine a where \n combine :: a -> a -> a\n\ninstance Combine String where \n combine = (++)\n\ninstance Num a => Combine a where \n combine = (+)\n\nand get confused when it fails to compile.\n\nSo why does the following code overlap?\n\n`String` is not an instance of `Num` so it would seem the compiler could see the instances as non-overlapping.\n\nIt turns out type checking is split into passes. Instance selection happens first and later the type checker ensures constraints like `Num a` are satisfied.\n\nTo tell if two instances overlap one, has to ignore the context portions of the instance declaration.\n\nLet’s line up the two instances and see if they overlap.\n\nCombine String \nCombine a\n\nSo do they? Well, I haven’t really defined what it means for instances to overlap.\n\nInstance selection is like a form of pattern matching. Each instance is analogous to a different equation that performs a match and instead of matching data constructors, the matches use type constructors and type variables.\n\n### Pattern Matching Review\n\nHere is a function with some normal pattern matching.\n\nasInt True = 1 \nasInt a = 0\n\nDo the matches overlap? Yes. The second pattern is a wildcard and matches everything. There is nothing ambiguous here because pattern matching is able to use the order of the matches to determine how to handle the overlap.\n\nThe compiler will complain if you switch the order because the more specific match will never get hit.\n\nasInt a = 0 \nasInt True = 1\n\nInstance selection works like pattern matching except on the type level. However, there is no way to specify an order, so an overlap causes a compiler error unconditionally.\n\nThis leads to a heuristic for using type classes. If you ever write an instance like `instance Combine a` you are saying that there can only be one instance for the type class. This begs the question of why use a type class at all? The answer is probably “don’t use a type class.”\n\n### Everything Works But You Still Fail\n\nLet’s keep using our mistaken instance to see how instance selection can succeed but compilation will fail.\n\nLet’s write out the instance signatures and remove the overlapping instance.\n\nclass Combine a where \n combine :: a -> a -> a\n\ninstance Num a => Combine a where \n combine :: Num a => a -> a -> a \n combine = (+)\n\nWe can now use `combine`\n\nmain = putStrLn $ combine “hello “ “world”\n\nBehind the scenes the compiler has made a version of `combine` based on our instance [declaration](https://hackernoon.com/tagged/declaration) and, let’s call it `combine_num` (for a more detailed explanation of what a compiler does look at this [post](https://www.schoolofhaskell.com/user/jfischoff/instances-and-dictionaries)).\n\nThe compiler sees a use of `combine` in `main` and must satisfy the constraint `Combine a`. It infers that `a` in this case is of type `String`. It must now satisfy the specialized constraint `Combine String`. The compiler looks at its instances and tries to find something that will match.\n\nThe compiler doesn’t have a `Combine String` but it does have a `Combine a`. `a` will match `String` because it is wildcard that matches everything.\n\nThe compiler substitutes in `combine_num`.\n\nmain = putStrLn $ combine\\_num “hello “ “world”\n\n`combine_num` brings with it the constraint `Num a`, which is specialized here to `Num String`. This constraint leads to another search for an instance for `Num String`, but there is no match this time and compilation fails.\n\nUsing a type class method adds a class constraint for which the compiler must solve. Solving the constraint requires finding a suitable instance, which can result in the compiler having to solve more constraints. All the constraints must be satisfied for compilation to succeed but they are not solved at the same time.\n\n### Trickier Overlap\n\nLet’s say you want to write a type class that counts how many arguments a function has:\n\nclass ArgCount a where \n argCount :: a -> Int \n \ninstance ArgCount (a -> b) where \n argCount \\_ = 1 \n \ninstance ArgCount (x -> y -> z) where \n argCount \\_ = 2\n\nLet’s line up our declarations like before:\n\nArgCount (a -> b) \nArgCount (x -> y -> z)\n\nDo they overlap? They do (otherwise I would not have asked the question :p). Adding parentheses will make the reason clearer.\n\nArgCount (a -> b) \nArgCount (x -> (y -> z))\n\nThe `b` in the first instance can be anything, even `y -> z` so it will match the second instance and we do have overlap.\n\nIf you are still confused by this example, it might be because of the infix notation. Pattern matching with constructors typically is in prefix notation (but it doesn’t have to be). Here are the same examples written out in prefix form:\n\nArgCount (-> a b ) \nArgCount (-> x (y -> z))\n\nLet’s try to fix this situation with recursion.\n\n\\-- I upgraded to using proxies so I would not have to use undefined \nclass ArgCount a where \n argCount :: p a -> Int \n \ninstance ArgCount b => ArgCount (a -> b) where \n argCount \\_ = 1 + argCount (Proxy :: Proxy b) \n \ninstance ArgCount (m a) where \n argCount \\_ = 0\n\nThe idea is that I will be able to count functions that are monadic where the final result is something like `State Int` or `IO a`. Unfortunately, this will also overlap.\n\nArgCount (m a) \nArgCount (a -> b)\n\nAgain this is clearer when written in prefix form.\n\nArgCount (m a) \nArgCount ((-> a) b)\n\nWe can see that `m` could be `-> a` so we have overlap.\n\nThe code below will work for counting the number of args for `IO` functions.\n\nclass ArgCount a where \n argCount :: p a -> Int \n \ninstance ArgCount b => ArgCount (a -> b) where \n argCount \\_ = 1 + argCount (Proxy :: Proxy b) \n \ninstance ArgCount (IO a) where \n argCount \\_ = 0\n\nA similar pattern is used by `[Printf](http://hackage.haskell.org/package/base-188.8.131.52/docs/Text-Printf.html#t:PrintfType)`.\n\nSo a few things to notice.\n\nThe less polymorphic an instance is, the less likely you are to get overlap. Sometimes you might think that your instance is relatively specific ( `a -> b` is only for functions of one argument) but because of possible substitutions, it is actually is much more general ( `a -> b` is really an instance for all functions).\n\n### When More Polymorphism Means Better Inference\n\nLet’s work through one final instance selection example: a trick for getting better type inference. This code is take from `mono-traversable` `[Data.Sequences](https://hackage.haskell.org/package/mono-traversable-1.0.2/docs/src/Data-Sequences.html#line-1488)` but was also present in `[Printf](http://hackage.haskell.org/package/base-184.108.40.206/docs/Text-Printf.html#t:PrintfType)`\n\ninstance (c ~ Char) => Textual \\[c\\] where \n words = List.words\n\nIf we ignore the context, we see that this is an instance of `Textual` for all types of lists regardless of the element type. However, the code will actually only compile if the type of list is `[Char]` or `String`.\n\nThere are cases where the type checker might be able to infer that it needs an instance for a `[c]` and, after the substitution of `words`, determine at some later stage that the list is really a `String`. If we had written the instance just for `String,` instance selection could have failed without a type annotation.\n\nAlthough it is not the typical situation, if you only need one specialized instance of a polymorphic type, this is a better way to go than using `FlexibleInstance` … at least from a type inference perspective.\n\n### Type Classes Are Awesome\n\nMany Haskellers have bad memories of failed attempts to use type classes successfully. My hope is by demystifying how type class instance selection works, we can avoid undue anguish.\n\nI only covered simple vanilla type classes without any specific type class extensions. It is tempting to think overlap issues can me remedied through enabling `OverlappingInstances` (and the more modern `Overlapping` and `Overlaps` pragmas) but it is by no means a panacea. Covering what can be accomplished with the useful type class extensions is at least a blog post on it’s own.\n\nIn my next blog post I’ll talk about some simple patterns for writing type classes that you can use for fun and profit.\n\nPS. Thanks to Sukant Hajra, Alan Zimmerman and Sudhir Kumar for early review and initial [feedback](https://hackernoon.com/tagged/feedback).\n\n> [Hacker Noon](http://bit.ly/Hackernoon) is how hackers start their afternoons. We’re a part of the [@AMI](http://bit.ly/atAMIatAMI)family. We are now [accepting submissions](http://bit.ly/hackernoonsubmission) and happy to [discuss advertising & sponsorship](mailto:firstname.lastname@example.org) opportunities.\n\n> To learn more, [read our about page](https://goo.gl/4ofytp), [like/message us on Facebook](http://bit.ly/HackernoonFB), or simply, [tweet/DM @HackerNoon.](https://goo.gl/k7XYbx)\n\n> If you enjoyed this story, we recommend reading our [latest tech stories](http://bit.ly/hackernoonlatestt) and [trending tech stories](https://hackernoon.com/trending). Until next time, don’t take the realities of the world for granted!