Haskell Non-exhaustive patterns in function for [(Int,Int)] -> [Int] [duplicate] - haskell

Is there a way to get GHCi to produce better exception messages when it finds at runtime that a call has produced value that does not match the function's pattern matching?
It currently gives the line numbers of the function which produced the non-exhaustive pattern match which though helpful at times does require a round of debugging which at times I feel is doing the same set of things over and over. So before I tried to put together a solution I wanted to see if something else exists.
An exception message that in addition to giving the line numbers shows what kind of call it attempted to make?
Is this even possible?

Try turning on warnings in ghci. This enables the compile time warnings you can get with ghc by passing -W, for example. You can do this several ways:
ghci -fwarn-incomplete-patterns
Or Neil Mitchell describes how he sets this up in his .ghci. Here is the relevant excerpt:
:set -fwarn-incomplete-patterns
You can manually enter this at ghci as well, but it would be a pain to do so each time you start it. Entered this way, it only works for statements entered at the prompt, not for loading files with :l. Instead you can put this comment at the top of the file you want to warn about incomplete patterns:
{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}

I recognize that this is something of a non-answer to your question, but my impression is that among veteran Haskell programmers there's a general consensus that non-exhaustive patterns should be avoided in the first place, even to the point of using -Werror to generate errors instead of just warnings.
I'm not sure how well that works in combination with GHCi, however, especially if you're writing functions at the prompt instead of loading a file--I can imagine it getting in the way more than it helps for working interactively. Running GHCi with the appropriate command-line flags seems to get the desired result for me, though.
If you want a more drastic solution to non-exhaustive patterns, you could always port Catch to work with modern GHC versions. Heh.
Beyond that, if you're using non-exhaustive patterns because the function really, truly, should never be called with some values, the missing cases can be filled in with something like error $ "function foo called with ridiculous arguments " ++ show blahBlah, if knowing the invalid arguments would be helpful. Alternately, you could try to rework your code or define more specialized data types such that functions can always do something sensible with any non-bottom argument.
Otherwise, I think you're stuck with awkward debugging.

Related

Module Frames - TableTypes does not work

I am a data scientist familiar with languages such as R and python.
I have been trying to learn haskell for two months.
There is a module people employ to deal with frames in haskell similarly to common packages in those other languages (tidyverse in R and pandas in python).
The problem is: the common function for extracting data type for a csv is simply returning a message error:
tableTypes "base" "base.csv"
<interactive>:2:1: error:
• No instance for (Show Language.Haskell.TH.Lib.DecsQ)
arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it
I cannot understand what this message means and I could not find any answer on Google. Could someone help me solve it?
Link to the module: http://hackage.haskell.org/package/Frames
You've stumbled into a case that's involves some advanced features of Haskell. The problem is that tableTypes "base" "base.csv" is a template haskell splice. For some reason, a few years back ghc was modified to allow bare expressions at the top level as splices, instead of requiring the standard splice syntax of $(expression generating code to splice).
But the bare expression syntax is incompatible with ghci. If you enter a bare expression in ghci, it tries to evaluate and print it (with some special rules for expressions that result in IO values).
When ghci evaluates tableTypes "base" "base.csv" it gets a result back that's not an instance of Show, because the template haskell Q environment is not printable. It contains a bunch of functions.
You have a few options here, depending on what you actually are trying to do. You could use runQ in ghci to dump the AST generated by the splice. That's probably not what you want. That's more likely to be a tool that's useful when you're developing a splice than for testing a library that uses them.
You could enable the TemplateHaskell extension within ghci and actually have it perform the splice interactively, but that's somewhat fiddly to get to work and you don't end up seeing much anyway.
I think the most practical solution is to move your code into a file. You can load said file from ghci if you desire - the important part is that in the context of a file, there's no longer any syntactic ambiguity - that's definitely a splice to evaluate while compiling, not an expression to evaluate interactively.

How does the presence of the "error" function bear on the purity of Haskell?

I've always wondered how the Haskell exception system fits in with the whole "Pure functional language" thing. For example see the below GHCi session.
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> head []
*** Exception: Prelude.head: empty list
Prelude> :t head
head :: [a] -> a
Prelude> :t error
error :: [Char] -> a
Prelude> error "ranch"
*** Exception: ranch
CallStack (from HasCallStack):
error, called at <interactive>:4:1 in interactive:Ghci1
Prelude>
The type of head is [a] -> a. But when you call it on the special case of an empty list, you get an exception instead. But this exception is not accounted for in the type signature.
If I remember correctly it's a similar story when there is a failure during pattern matching. It doesn't matter what the type signature says, if you haven't accounted for every possible pattern, you run the risk of throwing an exception.
I don't have a single, concise question to ask, but my head is swimming. What was the motivation for adding this strange exception system to an otherwise pure and elegant language? Is it still pure but I'm just missing something? If I want to take advantage of this exception feature, how would I go about doing it (ie how do I catch and handle exceptions? is there anything else I can do with them?) For example, if ever I write code that uses the "head" function, surely I should take precautions for the case where an empty list somehow smuggles itself in.
You are confusing two concepts: purity and totality.
Purity says that functions have no side effects.
Totality says that every function terminates and produces a value.
Haskell is pure, but is not total.
Outside of IO, nontermination (e.g., let loop = loop in loop) and exceptions (e.g., error "urk!") are the same – nonterminating and exceptional terms, when forced, do not evaluate to a value. The designers of Haskell wanted a Turing-complete language, which – as per the halting problem – means that they forwent totality. And once you have nontermination, I suppose you might as well have exceptions, too – defining error msg = error msg and having calls to error do nothing forever is much less satisfying in practice than actually seeing the error message you want in finite time!
In general, though, you're right – partial functions (those which are not defined for every input value, like head) are ugly. Modern Haskell generally prefers writing total functions instead by returning Maybe or Either values, e.g.
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x
errHead :: [a] -> Either String a
errHead [] = Left "Prelude.head: empty list"
errHead (x:_) = Right x
In this case, the Functor, Applicative, Monad, MonadError, Foldable, Traversable, etc., machinery makes combining these total functions and working with their results easy.
Should you actually come across an exception in your code – for instance, you might use error to check a complicated invariant in your code that you think you've enforced, but you have a bug – you can catch it in IO. Which returns to the question of why it's OK to interact with exceptions in IO – doesn't that make the language impure? The answer is the same as that to the question of why we can do I/O in IO, or work with mutable variables – evaluating a value of type IO A doesn't produce the side effects that it describes, it's just an action that describes what a program could do. (There are better descriptions of this elsewhere on the internet; exceptions aren't any different than other effects.)
(Also, note that there is a separate-but-related exception system in IO, which is used when e.g. trying to read a file that isn't there. People are often OK with this exception system, in moderation, because since you're in IO you're already working with impure code.)
For example, if ever I write code that uses the "head" function, surely I should take precautions for the case where an empty list somehow smuggles itself in.
A simpler solution: don't use head. There are plenty of replacements: listToMaybe from Data.Maybe, the various alternative implementations in the safe package, etc. The partial functions [1] in the base libraries -- specially ones as easy to replace as head -- are little more than historical cruft, and should be either ignored or replaced by safe variants, such as those in the aforementioned safe package. For further arguments, here is an entirely reasonable rant about partial functions.
If I want to take advantage of this exception feature, how would I go about doing it (ie how do I catch and handle exceptions? is there anything else I can do with them?)
Exceptions of the sort thrown by error can only be caught in the IO monad. If you are writing pure functions you won't want to force your users to run them in the IO monad merely for catching exceptions. Therefore, if you ever use error in a pure function, assume the error will not be caught [2]. Ideally you shouldn't use error in pure code at all, but if you are somehow compelled to do so, at least make sure to write an informative error message (that is, not "Prelude.head: empty list") so that your users know what is going on when the program crashes.
If I remember correctly it's a similar story when there is a failure during pattern matching. It doesn't matter what the type signature says, if you haven't accounted for every possible pattern, you run the risk of throwing an exception.
Indeed. The only difference from using head to writing the incomplete pattern match (\(x:_) -> x) by yourself explicitly is that in the latter case the compiler will at least warn you if you use -Wall, while with head even that is swept under the rug.
I've always wondered how the Haskell exception system fits in with the whole "Pure functional language" thing.
Technically speaking, partial functions don't affect purity (which doesn't make them any less nasty, of course). From a theoretical point of view, head [] is just as undefined as things like foo = let x = x in x. (The keyword for further reading into such subtleties is "bottom".)
[1]: Partial functions are functions that, just like head, are not defined for some values of the argument types they are supposed to take.
[2]: It is worth mentioning that exceptions in IO are a whole different issue, as you can't trivially avoid e.g. a file read failure just by using better functions. There are quite a few approaches towards handling such scenarios in a sensible way. If you are curious about the issue, here is one "highly opinionated" article about it that is illustrative of the relevant tools and trade-offs.
Haskell does not require that your functions be total, and doesn't track when they're not. (Total functions are those that have a well defined output for every possible value of their input type)
Even without exceptions or pattern match failures, you can have a function that doesn't define output for some inputs by just going on forever. An example is length (repeat 1). This continues to compute forever, but never actually throws an error.
The way Haskell semantics "copes" with this is to declare that there is an "extra" value in every single type; the so called "bottom value", and declare that any computation that doesn't properly complete and produce a normal value of its type actually produces the bottom value. It's represented by the mathematical symbol ⊥ (only when talking about Haskell; there isn't really any way in Haskell to directly refer to this value, but undefined is often also used since that is a Haskell name that is bound to an error-raising computation, and so semantically produces the bottom value).
This is a theoretical wart in the system, since it gives you the ability to create a 'value' of any type (albeit not a very useful one), and a lot of the reasoning about bits of code being correct based on types actually relies on the assumption that you can't do exactly that (if you're into the Curry-Howard isomorphism between pure functional programs and formal logic, the existence of ⊥ gives you the ability to "prove" logical contradictions, and thus to prove absolutely anything at all).
But in practice it seems to work out that all the reasoning done by pretending that ⊥ doesn't exist in Haskell still generally works well enough to be useful when you're writing "well-behaved" code that doesn't use ⊥ very much.
The main reason for tolerating this situation in Haskell is ease-of-use as a programming language rather than a system of formal logic or mathematics. It's impossible to make a compiler that could actually tell of arbitrary Haskell-like code whether or not each function is total or partial (see the Halting Problem). So a language that wanted to enforce totality would have to either remove a lot of the things you can do, or require you to jump through lots of hoops to demonstrate that your code always terminates, or both. The Haskell designers didn't want to do that.
So given that Haskell as a language is resigned to partiality and ⊥, it may as well give you things like error as a convenience. After all, you could always write a error :: String -> a function by just not terminating; getting an immediate printout of the error message rather than having the program just spin forever is a lot more useful to practicing programmers, even if those are both equivalent in the theory of Haskell semantics!
Similarly, the original designers of Haskell decided that implicitly adding a catch-all case to every pattern match that just errors out would be more convenient than forcing programmers to add the error case explicitly every time they expect a part of their code to only ever see certain cases. (Although a lot of Haskell programmers, including me, work with the incomplete-pattern-match warning and almost always treat it as an error and fix their code, and so would probably prefer the original Haskell designers went the other way on this one).
TLDR; exceptions from error and pattern match failure are there for convenience, because they don't make the system any more broken than it already has to be, without being quite a different system than Haskell.
You can program by throwing and catch exceptions if you really want, including catching the exceptions from error or pattern match failure, by using the facilities from Control.Exception.
In order to not break the purity of the system you can raise exceptions from anywhere (because the system always has to deal with the possibility of a function not properly terminating and producing a value; "raising an exception" is just another way in which that can happen), but exceptions can only be caught by constructs in IO. Because the formal semantics of IO permit basically anything to happen (because it has to interface with the real world and there aren't really any hard restrictions we can impose on that from the definition of Haskell), we can also relax most of the rules we usually need for pure functions in Haskell and still have something that technically fits in the model of Haskell code being pure.
I haven't used this very much at all (usually I prefer to keep my error handling using things that are more well-defined in terms of Haskell's semantic model than the operational model of what IO does, which can be as simple as Maybe or Either), but you can read about it if you want to.

Ghc: partially compile Haskell code?

When I compile a Haskell file with ghci, typically with :load, and if there is no type error, all the expressions are loaded in the ghc interpreter. It's very nice: I can play around with :t to figure out the type of various expressions.
My problem is: if there is a tiny error somewhere, ghci is not able to load anything (not even the imported modules!!), which makes finding the right types even more difficult. I always do the same: comment out all the bits that do not typecheck, find the relevant types wiht :t in ghci, and de-comment.
But this is so tedious! Is there a better workflow for "partially compiling" a Haskell source code?
As #MikhailGlushenkov pointed out in the comments, the solution is to use the -fdefer-type-errors flag to GHCi.

Haskell 'showInt' not in scope: why not?

I'm trying to understand Philip Wadler's "Essence of Functional Programming", and I seem to be held back by his assertion that "No knowledge of Haskell is necessary to understand this paper." Maybe not, but his examples sure require some.
Specifically, I'm trying to understand his example interpreter. When I try to compile this using GHC, or load it using :load, it complains not in scope: showint. Perhaps you meant showInt. When I replace the token with showInt, it says Not in scope: showInt.
I'd really like to believe Dr. Wadler when he says all I need to know is contained in his paper.
I'd really like to get it working under GHCI, so I can try various expressions under the interpreter. I'm new to Haskell, and was duly warned about the opaqueness of its error messages, but this seems designed to perplex!
The showInt function is part of the Numeric module, so you have to import Numeric to have it in scope. I guess the typo hint system knows about modules you haven't imported.
showInt also doesn't return a string directly but instead a String -> String function. I think this functionality is used for showing things composed of multiple parts more efficiently, but here it'd just be a pain and your code won't typecheck as is.
Instead, you can replace showint with just show and let the compiler figure it out. show is Haskell's toString and is overloaded for any type it's reasonable to convert to a string.

Can I get warnings about overly-restrictive type signatures?

Can GHC or some lint tool tell me when I've provided a type signature for a function that could be more polymorphic?
GHC doesn't do this, and a quick search of Hackage turns up nothing.
A simple, but possibly quite effective way to implement such a thing would be to load the module in GHCi, use :browse to get all the type signatures, then load a copy without any type signatures, use :browse again, and compare the two outputs; then just print all the lines that differ beyond parentheses, whitespace and alpha-renaming. However, this wouldn't work perfectly, especially if you have definitions whose types can't be inferred.
I have a feeling such a tool would turn up a lot of false positives in practice.

Resources