Haskell 'showInt' not in scope: why not? - haskell

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.

Related

Runtime "type terms" in LiquidHaskell vs. Idris

I have been playing around with LiquidHaskell and Idris lately and i got a pretty specific question, that i could not find a definitive answer anywhere.
Idris is a dependently typed language which is great for the most part. However i read that some type terms during type checking can "leak" from compile-time to run-time, even tough Idris does its best to eliminate those terms (this is a special feature even..). However, this elimination is not perfect and sometimes it does happen. If, why and when this happens is not immediately clear from the code and sometimes has an effect on run-time performance.
I have seen people prefering Haskells' type system, because it cannot happen there. When type checking is done, it is done. Types are "thrown away" and not used during run-time.
What is the story for LiquidHaskell? It enhances the type system capabilities quite a bit over traditional Haskell. Does LiquidHaskell also inject run-time bits for certain type "constellations" or (as i suspect) just adds another layer of "better" types over Haskell that do not affect run-time in any shape or form.
Meaning, if one removes the special LiquidHaskell type annotations and compiles it with standard GHC, is the code produced always the same? In other words: Is the LiquidHaskell extension compile-time only?
If yes, this seems like the best of both worlds, or is LiquidHaskell just not as expressive in the type system as Idris and therefore manages without run-time terms?
To answer your question as asked: Liquid Haskell allows you to provide annotations that a separate tool from the compiler verifies. Code is still compiled exactly the same way.
However, I have quibbles with your question as asked. It can be argued that there are cases in which some residue of the type must survive at run time in Haskell - especially when polymorphic recursion is involved. Consider this function:
lots :: Show a => Int -> a -> String
lots 0 x = show x
lots n x = lots (n-1) (x,x)
There is no way to statically determine the exact type involved in the use of show. Something derived from the types must survive to runtime. In practice, this is easy to do by using type class dictionaries. The theoretically important detail is that there's still type-directed behavior being chosen at runtime.

Function searching for applicable types for applying to Lensed pieces of Haskell AST

My primary queston is: is there, within some Haskell AST, a way I can determine a list of the available declarations, and their types? I'm trying to build an editor that allows for the user to be shown all the appropriate edits available, such as inserting functions and/or other declared values that can be used or inserted at any point. It'll also disallows syntax errors as well as type-errors. (That is, it'll be a semantic structural editor, which I'll also use the typechecker to make sure the editing pieces make sense to in this case, Haskell).
The second part of my question is: once I have that list, given a particular expression or function or focussed-on piece of AST (using Lens), how could I filter the list based on what could possibly replace or fit that particular focussed-on AST piece (whether by providing arguments to a function, or if it's a value, just "as-is"). Perhaps I need to add some concrete example here... something like: "Haskell, which declarations could possibly be applied (for functions) and/or placed into the hole at yay x y z = (x + y - z) * _?" then if there was an expression number2 :: Num a => a ; number2 = 23 it would put this in the list, as well as the functions available in the context, as well as those from Num itself such as (+) :: Num a => a -> a -> a, (*) :: Num a => a -> a -> a, and any other declarations that resulted in a type that would match such as Num a => a etc. etc.
More details follow:
I’ve done a fair bit of research into this area over quite a long time: looked at and used hint, Language.Haskell.Exts and Control.Lens a fair bit. Also had a look into Dynamic. Control.Lens is relevant for the second half of my question. I've also looked at quite a few projects along the way including Conal Elliott's "Semantic Editing Combinators", Paul Chiusano's Unison system and quite a few things in Clojure and Lisp as well.
So, I know I can get a list of the exports of a module with hint as [String], and I could coerce that to [Dynamic], I think (possibly?), but I’m not sure how I’d get sub-function declarations and their types. (Maybe I could take the declarations within that scope with AST and put them in their own modules in a String and pull them in by getting the top level declarations with hint? that would work but feels hacky and cumbersome)
I can use (:~:) from Data.Typeable to do "propositional equality" (ie typechecking?) on two terms, but what I actually need to do is see if a term could be matched into a position in the source/AST (I'm using lenses and prisms to focus on those parts of the AST) given some number of arguments. Some kind of partial type-checking, or result type-checking? Because the thing I might be focussing on could very well be a function, and I might need to keep the same arity.
I feel like perhaps this is very similar to Idris' term-searching, though I haven't looked into the source for that and I'm not sure if that's something only possible in a dependently typed language.
Any help would be great.
Looks like I kind of answered my own questions, so I'm going to do so formally here.
The answer to the first part of my question can be found in the Reflection module of the hint library. I knew I could get a list a [String] of these modules, but there's a function in there that can be used which has type: getModuleExports :: MonadInterpreter m => ModuleName -> m [ModuleElem] and is most likely the sort of thing I'm after. This is because hint provides access to a large part of the GHC API. It also provides some lookup functions which I can then use to get the types of these top level terms.
https://github.com/mvdan/hint/blob/master/src/Hint/Reflection.hs#L30
Also, Template Haskell provides some of the functionality I'm interested in, and I'll probably end up using quite a bit of that to build my functions, or at least a set of lenses for whatever syntax is being used by the code (/text) under consideration.
In terms of the second part of the question, I still don't have a particularly good answer, so my first attempt will be to use some String munging on the output of the lookup functions and see what I can do.

Is it possible to emit raw source code with Template Haskell?

Say I have a String (or Text or whatever) containing valid Haskell code. Is there a way to convert it into a [Dec] with Template Haskell?
I'm pretty sure the AST doesn't directly go to GHC so there's going to be a printing and then a parsing stage anyways.
This would be great to have since it would allow different "backends" for TH. For example you could use the AST from haskell-src-exts which supports more Haskell syntax than TH does.
I'm pretty sure the AST doesn't directly go to GHC so there's going to be a printing and then a parsing stage anyways.
Why would you think that? That isn’t the case, the TH AST is converted to GHC’s internal AST directly; it never gets converted back to text at any point in that process. (If it did, that would be pretty strange.)
Still, it would be somewhat nice if Template Haskell exposed a way to parse Haskell source to expressions, types, and declarations, basically exposing the parsers behind various e, t, and d quoters that are built in to Template Haskell. Unfortunately, it does not, and I don’t believe there are currently any plans to change that.
Currently, you need to go through haskell-src-exts instead. This is somewhat less than ideal, since there are differences between haskell-src-exts’s parser and GHCs, but it’s as good as you’re currently going to get. To lessen the pain, there is a package called haskell-src-meta that bridges haskell-src-exts and template-haskell.
For your use case, you can use the parseDecs function from Language.Haskell.Meta.Parse, which has the type String -> Either String [Dec], which is what you’re looking for.

What is a good reason to use a type signature for functions when the compiler can infer the types

I am trying to code using 'good Haskell style' and so am trying to follow typical coding standards I find around. Also, compiling with -Wall and -Werror as I am used to when coming from C. One of the warnings I frequently get is "Top level binding with no type signature" and then the compiler tells me what the type signature should be.
I am missing what the advantage of having the type signature explicitly defined is. As a concrete example:
-- matchStr :: String -> String -> Maybe (String)
matchStr str s
| isPrefixOf str s = Just(drop (length str) s)
| otherwise = Nothing
Now what happens if I want to change the type from String to ByteString to improve performance; I'll have to import the ByteString package and use a qualified version of some functions. No other changes are necessary. If I have the type signature then I also have to change this and yet the Haskell compiler would notice this change and correctly infer the new types.
So what am I missing? Why is it considered a good idea to explicitly put type signatures on functions in the general case? i.e. I understand that there might be exceptions where it is a good idea, but why is it considered good in general?
If you make a mistake in defining your function, the compiler might infer a type that isn't what you expected it to be. If you've declared the type you expect, the compiler will report the error in the function's definition.
Without the declaration, the compiler has no way to know that its inferred type is "wrong", and it will instead end up reporting errors in the places where you try to call the function, which makes it less clear where the problem really lies.
If the calling functions don't have type declarations either, then instead of reporting errors there, the compiler might just infer incorrect types for those too, causing problems in their callers. You'll end up getting an error message somewhere, but it may be quite far removed from the actual root of the problem.
Also, you can declare a more specific type than what the compiler would infer. For example, if you write the function:
foo n = n + 1
The compiler will infer the type Num a => a -> a, which means it must compile generic code that can work with any Num instance. If you declare the type as Int -> Int, the compiler may be able to produce more efficient code that's specialized for integers only.
Finally, type declarations serve as documentation. The compiler may be able to infer the types of complex expressions, but it's not so easy for a human reader. A type declaration provides the "big picture" that can help a programmer understand what the function does.
Note that Haddock comments are attached to declarations, not definitions. Writing a type declaration is the first step toward providing additional documentation for a function using Haddock.
I would consider documentation one advantage of having an explicit type signature.
From "Types and Programming Languages":
Types are also useful when reading programs. The type declarations in procedure headers and module interfaces constitute a form of documentation, giving useful hints about behavior. Moreover, unlike descriptions embedded in comments, this form of documentation cannot become outdated, since it is checked during every run of the compiler. This role of types is particularly
important in module signatures.
There are several reasons.
It may make the code easier for humans to read. (OTOH, if you have dozens of tiny definitions, sometimes the type signatures add more clutter.)
If your implementation is wrong, the compiler may infer the wrong type. This may cause other functions' types to be inferred wrong, finally resulting in a type error very far away from the actual broken function.
You may want to give a function a less polymorphic type than it could have, for performance reasons.
You may want to use type aliases. This allows you to quickly change a type in several places, and also to document some of the intent behind a value. (Compare FilePath vs String.)
The compiler can figure out types automatically, but not all external tools can do this. (E.g., originally Haddock would refuse to produce documentation for functions lacking an explicit type signature - although I gather this is fixed now.)
It is worth noting that some people advocate that you start with the type signatures, and fill in the implementations later.
At any rate, most people seem to recommend type signatures for all or most top-level declarations. Whether you give them for local variables / functions is a matter of taste.
Your contrived example is really contrived, since the function body does not depend on the type of contents of the list. In this case it is indeed difficult to see what's the benefit of defining the type to be [String] -> ([String],[String]) instead of [a]->([a],[a])
If you attempt to define a function that depends on the contents, you will see that the type definition is not the only thing you need to change. For example, changing a list for MArray is going to be far more involved, not just using a function that happens to have the same name in a different module. So qualifying the name during refactoring in a few narrow cases is not a good enough reason to not specify type signatures.
Specifying the type tells the compiler a little bit of the intent. Then the compiler will be able to report the mismatch of the intent and the implementation.

When to exploit type inference in Haskell?

I'm curious as to how often experienced Haskell programmers really use type inference in practice. I often see it praised as an advantage over the always-explicit declarations needed in certain other languages, but for some reason (perhaps just because I'm new) it "feels" right to write a type signature just about all the time... and I'm sure in some cases it really is required.
Can some experienced Haskellers (Haskellites? Haskellizers?) provide some input?
It's still an advantage, even if you write type signatures, because the compiler will catch type errors in your functions. I usually write type signatures too, but omit them in places like where or let clauses where you actually define new symbols but don't feel the need to specify a type signature.
Stupid example with a strange way to calculate squares of numbers:
squares :: [Int]
squares = sums 0 odds
where
odds = filter odd [1..]
sums s (a:as) = s : sums (s+a) as
square :: Int -> Int
square n = squares !! n
odds and sums are functions that would need a type signature if the compiler wouldn't infer them automatically.
Also if you use generic functions, like you usually do, type inference is what ensures that you really combine all those generic functions together in a valid way. If you, in the above example, say
squares :: [a]
squares = ...
The compiler can deduce that this isn't valid this way, because one of the used functions (the odd function from the standard library), needs a to be in the type class Integral. In other languages you usually only recognize this at a later point.
If you write this as a template in C++, you get a compiler error when you use the function on a non-Integral type, but not when you define the template. This can be quite confusing, because it's not immediately clear where you've gone wrong and you might have to look through a long chain of error messages to find the real source of the problem. And in something like python you get the error at runtime at some unexpected point, because something didn't have the expected member functions. And in even more loosely typed languages you might not get any error, but just unexpected results.
In Haskell the compiler can ensure that the function can be called with all the types specified in it's signature, even if it's a generic function that is valid for all types that fulfill some constrains (aka type classes). This makes it easy to program in a generic way and use generic libraries, something much harder to get right in other languages. Even if you specify a generic type signature, there is still a lot of type inference going on in the compiler to find out what specific type is used in each call and if this type fulfills all the requirements of the function.
I always write the type signature for top-level functions and values, but not for stuff in "where", "let" or "do" clauses.
First, top level functions are generally exported, and Haddock needs a type declaration to generate the documentation.
Second, when you make a mistake the compiler errors are a lot easier to decode if the compiler has type information available. In fact sometimes in a complicated "where" clause I get an incomprehensible type error so I add temporary type declarations to find the problem, a bit like the type-level equivalent of printf debugging.
So to answer the original question, I use type inference a lot but not 100% of the time.
You have good instincts. Because they are checked by the compiler, type signatures for top-level values provide invaluable documentation.
Like others, I almost always put a type signature for a top-level function, and almost never for any other declaration.
The other place type inference is invaluable is at the interactive loop (e.g., with GHCi). This technique is most helpful when I'm designing and debugging some fancy new higher-order function or some such.
When you are faced with a type-check error, although the Haskell compiler does provide information on the error, this information can be hard to decode. To make it easier, you can comment out the function's type signature and then see what the compiler has inferred about the type and see how it differs from your intended type.
Another use is when you are constructing an 'inner function' inside a top level function but you are not sure how to build the inner function or even what its type should be. What you can do is to pass the inner-function in as an argument to the top level function and then ask ghci for the type of the type level function. This will include the type of the inner function. You can then use a tool like Hoogle to see if this function already exists in a library.

Resources