Multiple words in function type declaration confuses me - haskell

I understand haskell's function type declaration like,
length :: String -> Int
prefix :: Int -> String -> String
But sometimes, the types on the right side are not simple types like String, Integer but it contains multiple literal words, and the words that look like custom defined etc.
For example, these types defined on this post,
withLocation :: Q Exp -> Q Exp
What does Q, Exp mean?
formatLoc :: Loc -> String
What does Loc mean? Is it part of haskell library?

The types Q, Exp and Loc are types from the Template Haskell module imported at the beginning of the source file.
Q is a parameterized type, just like, say, Maybe or IO from the prelude, which is here applied to Exp.
How to do goto defintion from emacs editor?
This can be achieved using Scion, but that won't help you for this use case as it does not allow you to jump into external libraries (which may not be available in source form anyway).

Related

What does a stand for in a data type declaration?

Normally when using type declarations we do:
function_name :: Type -> Type
However in an exercise I am trying to solve there is the following structure:
function_name :: Type a -> Type a
or explicitly as in the exercise
alphabet :: DFA a -> Alphabet a
alphabet = undefined
What does a stand for?
Short answer: it's a type variable.
At the computation level, the way we define functions is to use variables to refer to their arguments. Like this:
f x = x + 3
Here x is a variable, and its value will be chosen when the function is called. Haskell has a similar (but not identical...) mechanism in its type sublanguage. For example, you can write things like:
type F x = (x, Int, x)
type Endo a = a -> a -> a
Here again x is a variable in the first one (and a in the second), and its value will be chosen at use sites. One can also use this mechanism when defining new types. (The previous two examples just give new names to existing types, but the following does more.) One of the most basic nontrivial examples of this is the Maybe family of types:
data Maybe a = Nothing | Just a
The things on the right of the = are computation-level, so you can mostly ignore them for now, but on the left we are declaring a new family of types Maybe which accepts other types as an argument. For example, Maybe Int, Maybe (Bool, String), Maybe (Endo Char), and even passing in expressions that have variables like Maybe (x, Int, x) are all possible.
Syntactically, type constructors (things which are defined as part of the program text and that we expect the compiler to look up the definition for) start with an upper case letter and type variables (things which will be instantiated later and so don't currently have a concrete definition) start with lower case letters.
So, in the type signature you showed:
alphabet :: DFA a -> Alphabet a
I suspect there are actually two constructs new to you, not just one: first, the type variable a that you asked about, and second, the concept of type application, where we apply at the type level one "function-like" type to another. (Outside of this answer, people say "parameterized" instead of "function-like".)
...and, believe it or not, there is even a type system for types that makes sure you don't write things like these:
Int a -- Int is not parameterized, so shouldn't be applied to arguments
Int Char -- ditto
Maybe -> String -- Maybe is parameterized, so should be applied to
-- arguments, but isn't

Obtaining type information with Template Haskell

I'm currently working on a library that allows the user to specify a list of command specifications as follows:
data CommandDef = forall (as :: [*]). Typeable as => CommandDef {
argTypes :: Proxy as,
commandName :: String,
commandStrings :: [String],
parsers :: HList (FMap CommandParser as),
description :: Maybe String
}
This list of command specifications can then be passed into a template haskell function genCommands :: [CommandDef] -> Q [Dec] to generate a Command data type representing the different types of commands that the user has specified, together with a function parseCommands :: String -> Maybe Command, where argTypes specifies the types of the command's arguments to be parsed, and parsers is an HList of the relevant parsers for the given argTypes.
The issue is, I need to somehow get a Type (from Language.Haskell.TH) for each of the argTypes in a CommandDef in order to properly generate the Command type with Template Haskell -- while still keeping the type safety of making sure all of the parsers are of the appropriate type. (The idea is, if commandName = "CommandName and argTypes = Proxy #'[ArgType1, ArgType2], a constructor of form CommandName ArgType1 ArgType2 will be generated in the Command type.)
So, really, in an ideal world, what I would like is a function Proxy as -> Q [Type], or something similar, but I'm not sure if this is possible to do in Template Haskell.
Is there such a thing? Or is there any way my approach could be modified in order to accomplish all of the same goals with Template Haskell?
I have considered adding a redundant field argTypesTH :: [Name] which contains all of the names of the types in argTypes, but I'm not even sure how this could work, because I can't seem to find a template haskell function which takes a type name, and returns the needed Type that needs to be specified for the constructors of my Command type. (There is reifyType, but I'm not sure if that can do what I want, as that takes the name of a value and returns a type)

How does the :: operator syntax work in the context of bounded typeclass?

I'm learning Haskell and trying to understand the reasoning behind it's syntax design at the same time. Most of the syntax is beautiful.
But since :: normally is like a type annotation, How is it that this works:
Input: minBound::Int
Output: -2147483648
There is no separate operator: :: is a type annotation in that example. Perhaps the best way to understand this is to consider this code:
main = print (f minBound)
f :: Int -> Int
f = id
This also prints -2147483648. The use of minBound is inferred to be an Int because it is the parameter to f. Once the type has been inferred, the value for that type is known.
Now, back to:
main = print (minBound :: Int)
This works in the same way, except that minBound is known to be an Int because of the type annotation, rather than for some more complex reason. The :: isn't some binary operation; it just directs the compiler that the expression minBound has the type Int. Once again, since the type is known, the value can be determined from the type class.
:: still means "has type" in that example.
There are two ways you can use :: to write down type information. Type declarations, and inline type annotations. Presumably you've been used to seeing type declarations, as in:
plusOne :: Integer -> Integer
plusOne = (+1)
Here the plusOne :: Integer -> Integer line is a separate declaration about the identifier plusOne, informing the compiler what its type should be. It is then actually defined on the following line in another declaration.
The other way you can use :: is that you can embed type information in the middle of any expression. Any expression can be followed by :: and then a type, and it means the same thing as the expression on its own except with the additional constraint that it must have the given type. For example:
foo = ('a', 2) :: (Char, Integer)
bar = ('a', 2 :: Integer)
Note that for foo I attached the entire expression, so it is very little different from having used a separate foo :: (Char, Integer) declaration. bar is more interesting, since I gave a type annotation for just the 2 but used that within a larger expression (for the whole pair). 2 :: Integer is still an expression for the value 2; :: is not an operator that takes 2 as input and computes some result. Indeed if the 2 were already used in a context that requires it to be an Integer then the :: Integer annotation changes nothing at all. But because 2 is normally polymorphic in Haskell (it could fit into a context requiring an Integer, or a Double, or a Complex Float) the type annotation pins down that the type of this particular expression is Integer.
The use is that it avoids you having to restructure your code to have a separate declaration for the expression you want to attach a type to. To do that with my simple example would have required something like this:
two :: Integer
two = 2
baz = ('a', two)
Which adds a relatively large amount of extra code just to have something to attach :: Integer to. It also means when you're reading bar, you have to go read a whole separate definition to know what the second element of the pair is, instead of it being clearly stated right there.
So now we can answer your direct question. :: has no special or particular meaning with the Bounded type class or with minBound in particular. However it's useful with minBound (and other type class methods) because the whole point of type classes is to have overloaded names that do different things depending on the type. So selecting the type you want is useful!
minBound :: Int is just an expression using the value of minBound under the constraint that this particular time minBound is used as an Int, and so the value is -2147483648. As opposed to minBound :: Char which is '\NUL', or minBound :: Bool which is False.
None of those options mean anything different from using minBound where there was already some context requiring it to be an Int, or Char, or Bool; it's just a very quick and simple way of adding that context if there isn't one already.
It's worth being clear that both forms of :: are not operators as such. There's nothing terribly wrong with informally using the word operator for it, but be aware that "operator" has a specific meaning in Haskell; it refers to symbolic function names like +, *, &&, etc. Operators are first-class citizens of Haskell: we can bind them to variables1 and pass them around. For example I can do:
(|+|) = (+)
x = 1 |+| 2
But you cannot do this with ::. It is "hard-wired" into the language, just as the = symbol used for introducing definitions is, or the module Main ( main ) where syntax for module headers. As such there are lots of things that are true about Haskell operators that are not true about ::, so you need to be careful not to confuse yourself or others when you use the word "operator" informally to include ::.
1 Actually an operator is just a particular kind of variable name that is applied by writing it between two arguments instead of before them. The same function can be bound to operator and ordinary variables, even at the same time.
Just to add another example, with Monads you can play a little like this:
import Control.Monad
anyMonad :: (Monad m) => Int -> m Int
anyMonad x = (pure x) >>= (\x -> pure (x*x)) >>= (\x -> pure (x+2))
$> anyMonad 4 :: [Int]
=> [18]
$> anyMonad 4 :: Either a Int
=> Right 18
$> anyMonad 4 :: Maybe Int
=> Just 18
it's a generic example telling you that the functionality may change with the type, another example:

Haskell-(Type declaration) what is "a"?

This is perhaps a very basic question, but, nevertheless, it does not seem to have been covered on SO.
I recently took up Haskell and up until now type declarations consisted of mostly the following:
Int
Bool
Float
etc, etc
Now I am getting into lists and I am seeing type declarations that use a, such as in the following function that iterates through an associative list:
contains :: Int -> [(Int,a)] -> [a]
contains x list = [values | (key,values)<-list, x==key]
Can someone provide an explanation as to what this a is, and how it works? From observation it seems to represent every type. Does this mean I can input any list of any type as parameter?
Yes, you're right, it represents "any type" - the restriction being that all as in a given type signature must resolve to the same type. So you can input a list of any type, but when you use contains to look up a value in the list, the value you look up must be the same type as the elements of the list - which makes sense of course.
In Haskell, uppercase types are concrete types (Int, Bool) or type constructors (Maybe, Either) while lowercase types are type variables. A function is implicitly generic in all the type variables it uses, so this:
contains :: Int -> [(Int, a)] -> [a]
Is shorthand for this*:
contains :: forall a. Int -> [(Int, a)] -> [a]
In C++, forall is spelled template:
template<typename a>
list<a> contains(int, list<pair<int, a>>);
In Java and C#, it’s spelled with angle brackets:
list<a> contains<a>(int, list<pair<int, a>>);
Of course, in these languages, generic type variables are often called T, U, V, while in Haskell they’re often called a, b, c. It’s just a difference of convention.
* This syntax is enabled by the -XExplicitForAll flag in GHC, as well as other extensions.

GADT for polymorphic list

I am parsing a few statements of the form
v1 = expression1
v2 = expression2
...
I am using the State Monad and my state should be a pair of (String, Expr a), I really insist on having the expressions typed. I tried to implement the state as [PPair] where I define PPair by the GADT:
data PPair where
PPair :: (String, Expr a) -> PPair
Once this line passed the compiler, I felt that I am doing something really really wrong. I suppressed the thought and went on coding. When I came to writing the code that would extract the value of the variable from the State, I realized the problem:
evalVar k ((PPair (kk, v)):s) = if k == kk then v else evalVar k s
I get:
Inferred type is less polymorphic than expected
which is quite expected. How do I work around this problem? I know I can solve it by breaking up the type over all candidate types a, but is there no neater way?
The problem is that there's no possible type evalVar can have:
evalVar :: String -> [PPair] -> Expr ?
You can't say ? is a, because then you're claiming your return value works for any value of a. What you can do, however, is wrap up "an Expr with an unknown type" into its own data type:
data SomeExpr where
SomeExpr :: Expr a -> SomeExpr
or, equivalently, with RankNTypes rather than GADTs:
data SomeExpr = forall a. SomeExpr (Expr a)
This is called existential quantification. You can then rewrite PPair using SomeExpr:
data PPair = PPair String SomeExpr
and evalVar works out:
evalVar k (PPair kk v : xs)
| k == kk = v
| otherwise = evalVar k xs
(Of course, you could just use a [(String,SomeExpr)] instead, and the standard lookup function.)
In general, though, trying to keep expressions completely typed at the Haskell level like this is probably an exercise in futility; a dependently-typed language like Agda would have no trouble with it, but you'll probably end up running into something Haskell can't do quite quickly, or weakening things to the point where the compile-time safety you wanted out of the effort is lost.
That's not to say it never works, of course; typed languages were one of the motivating examples for GADTs. But it might not work as well as you want, and you'll probably run into trouble if your language has any non-trivial type system features like polymorphism.
If you really want to keep the typing, then I'd use a richer structure than strings to name variables; have a Var a type that explicitly carries the type, like this:
data PPair where
PPair :: Var a -> Expr a -> PPair
evalVar :: Var a -> [PPair] -> Maybe (Expr a)
A good way to achieve something similar to this would be to use the vault package; you can construct Keys from ST and IO, and use Vault as a heterogeneous container. It's basically like a Map where the keys hold the type of the corresponding value. Specifically, I'd suggest defining Var a as Key (Expr a) and using a Vault instead of your [PPair]. (Full disclosure: I've worked on the vault package.)
Of course, you'll still have to map the variable names to the Key values, but you could create all the Keys right after parsing, and carry those around instead of the strings. (It'd be a bit of work to go from a Var to its corresponding variable name with this strategy, though; you can do it with a list of existentials, but the solution is too long to put in this answer.)
(By the way, you can have multiple arguments to a data constructor with GADTs, just like regular types: data PPair where PPair :: String -> Expr a -> PPair.)

Resources