Haskell typing for Int's and Double's - haskell

Just quick question about typing.
If I type into ghci :t [("a",3)] I get back [("a",3)] :: Num t => [([Char], t)]
Inside a file I have defined a type as:
type list = [(String, Int)]
How can I change the type to support both Ints and Doubles with the type I have defined, similar to what I wrote in ghci?

First, you have an error in your code. Data types must start with capital letters:
type List = [(String, Int)]
(Note that String is a type synonym for [Char], i.e. they are exactly the same type). We'll solve your problem in a roundabout way. Note that you can make the type completely general in the second slot of the tuple:
type List a = [(String,a)]
so that your type parameterizes over arbitrary types. If you need to specialize to numeric types in some function, then you can make that specialization for each function individually. For example:
foo :: Num a => List a
foo = [("Hello",1),("World",2)]
We could have included a constraint in the data type, like this:
data Num a => List a = List [(String,a)]
but you would still have to include the constraint Num a => ... in every function declaration, so you don't actually save any typing. For this reason, Haskell programmers generally follow the rule "Don't include type constraints in data declarations."

Related

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:

Bind type parameter

I am currently working with the quite nice haskell-eigen library and stumbled upon a fundamental yet probably basic problem (I am quite new to practical haskell development).
I use their basic matrix type
data Matrix a b :: * -> * -> *
where a denotes the haskell and b the internal C type. This is realized via the restriction
Elem a b
with
Elem Double CDouble
Elem Float CFloat
-- more for complex types...
Although not really the question I want to ask here I kind of don't understand why this is done this way. Since it is obviously a kind of functional mapping I already don't understand why this is formulated as an equivalency relation, but anyway...
I now want to define (as a simple example - I got several) an instance of Key from the keys package. It defines the index key for a given container, for example
type instance [] = Int
So instances of Key are defined over types of kind * -> *.
However due to that requirement, this won't work:
type instance Key Matrix = (Int, Int)
I have to in some way make Matrix be of kind * -> *. So (coming from c++ where I would do this using traits classes), I tried this:
type family CType a where
CType Double = CDouble
CType Float = CFloat
type MatX a = Matrix a (CType a)
In other words I tried to use type synonyms as a means of realizing that above mentioned functional type map.
Now I tried the following:
type instance Key MatX = (Int, Int)
which gives me "The type synonym ‘MatX’ should have 1 argument, but has been given none" and I even tried the obviously wrong
type instance Key (MatX a) = (Int, Int)
which gives me "Expected kind * -> *, but MatX a has kind *". This sounds to me like "I the compiler expect a type with more than 0 but - being a type synonym - less than 1 argument".
So my question is: How does one commonly map types in haskell in order to solve such a kind mismatch or get rid of it in another way.
P.S.: I am well aware that the eigen matrix has an indexing function, but
I want it to be a common one with other data types
I have this problem in other variants for other type instances.
Edit: Added reference links to mentioned packages.
You're nearly there. The one missing piece is that type synonyms must be used saturated - that is, you have to supply all of its arguments. MatX on its own is not a valid type, only MatX a. The reason for this is that type synonyms are just synonyms - they're expanded at compile time, which means that the compiler needs to know all of the type synonym's arguments in order to get a valid type after expansion.
The fix is to change your type synonym to a newtype.
newtype MatX a = MatX { getMatX :: Matrix a (CType a) }
newtypes can be partially applied, because MatX a is now a different type to Matrix a (CType a).
type instance Key MatX = (Int, Int)
The other answer shows the general case for converting type synonyms into things that can be used in instance declarations. But in this specific case it can be much simpler: since the index type is the same for all different matrices, you can supply just the arguments needed to get the kind correct. Thus:
type instance Key (Matrix a) = (Int, Int)
No extra type families relating Haskell and C types needed, no new types needed. This will also make working with the keys' library's API much simpler, as you won't need to do any newtype wrapping and unwrapping around each call.

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.

How can I define a new data type that is a list of numbers?

I am a complete Haskell n00b, but I would like to define a new data type that is simple a list of numbers. How would I go about doing this? I've read Haskell wikibook on type declarations, as well as other online resources, but I cannot seem to figure it out. Here is, in essence, what I've tried:
type NumList = [Num]
That didn't work, so how can I do this? Thanks for the help.
Num is a class, not a type. Choose a type instead; e.g. Integer or Rational are probably good choices.
type NumList = [Integer]
However, this does not create a new type; it just creates a new name for an old type. If you actually want a new type, you can use newtype, as in
newtype NumList = MkNumList [Integer]
which defines a new type named NumList and a new data constructor named MkNumList.
The type keyword is just for type synonyms (new names of types that already exist), so you can't use a class like Num.
Instead, you might use the data keyword together with Haskell's context notation:
data Num a => NumList a = NumList [a]
Except when I try that in ghci, it scolds me because datatype contexts are deprecated. Apparently you're better off using a GADT. Perhaps something like:
data NumList a where
Empty :: Num a => NumList a
Singleton :: Num a => a -> NumList a
Append :: Num a => NumList a -> NumList a -> NumList a
There is several answers depending on your exact need. If you just want a list of number for specific applications you probably know what exact type of numbers you'll use in this case and should just use :
type DoubleList = [Double]
(With a more explicit name I hope since DoubleList presents no advantage whatsoever compared to [Double])
If you want to force every function that use NumList to use a Num a context (but it won't be automatic which is why this method is deprecated) you can use :
data Num a => NumList a = NL [a]
though that's probably a bad idea, it doesn't bring you anything over the use of (Num a) => ...[a].... in your code.
If you don't care what exact type of numbers is in your list, only that you can make operations between them (but not between two NumList), you can use existential types :
data NumList = forall a . (Num a) => NL [a]
This is most analogous to objects though with type erasure and no reflexion you won't be able to do much with your NumList (that can be added but by this point I'm pretty sure you're just piling difficulties you don't need just because you're trying to write Java/C++/Other in Haskell).
Note that if you want to create Num instances for list of numbers, you could just do :
instance (Num a) => Num [a] where ...
My ultimate recommendation would really be to use [a] with the appropriate Num a context but should you believe that to be erroneous you'll have to give more details on your use of this type if you are to receive further guidance.

Type Signature of functions with Lists in haskell

I am just beginning to learn Haskell and am following the book "Learnyouahaskell".I have come across this example
tell :: (Show a) => [a] -> String
tell [] = "The list is empty"
I understand that (Show a) here is a class constraint and the type of parameter , in this case a has to be able to be "showable" .
Considering that a here is a list and not an element of the list , why am i unable to declare the function like :-
tell :: (Show a) =>a->String
Edit 1:-from the answers below i seem to understand that one would need to specify the concrete type of a for pattern matching. Considering this,what would be a correct implementation of the below:-
pm :: (Show a) =>a->String
pm 'g'="wow"
It gives me the error as below
Could not deduce (a ~ Char)
from the context (Show a)
bound by the type signature for pm :: Show a => a -> String
at facto.hs:31:7-26
`a' is a rigid type variable bound by
the type signature for pm :: Show a => a -> String at facto.hs:31:7
In the pattern: 'g'
In an equation for `pm': pm 'g' = "wow"
Failed, modules loaded: none.
I understand from the error message that it s not able to deduce the concrete type of a , but then how can it be declared using Show.
I know I can solve the above like this:-
pmn :: Char->String
pmn 'g'="wow"
But I am just trying to understand the Show typeclass properly
List does implement Show type class but when you say: Show a => a -> String It means the function will accept any type which implements Show AND most importantly you can only call show class functions on a nothing else, your function will never know the concrete type of a. Whereas you are trying to call list pattern matching on a
Update for new edit in question:
The correct implementation would be: pm c ="wow". You can call any Show type class functions on parameter c. You cannot pattern match as you were trying before because you dont know the exact type of parameter, you only know that it implements Show type class. But when you specific Char as the type then the pattern matching works
In both signatures, a isn't a list -- it's any type at all, and you don't get to pick which (except that it must be an instance of Show).
In
tell₁ :: Show a => [a] -> String
tell₁ [] = "The list is empty"
... -- (remember to match the non-empty list case too!)
You're matching on the list of as, not on a value of type a itself.
If you wrote
tell₂ :: Show a => a -> String
tell₂ [] = "The list is empty"
...
You would be assuming that the type a is the type of lists (of something). But it could be any type at all, such as Bool.
(But it's possible that I don't understand your question -- you haven't really said what the problem is. When asking a question like this you should generally specify what you did, what you expected, and what happened. None of these is really specified here, so people can only guess at what you might've meant.)
The problem isn't with Show. Indeed if we try:
tell2 :: a -> String
tell2 [] = "The list is empty"
We get a type check error. Lets see what it says:
test.hs:5:7:
Couldn't match expected type `a' with actual type `[t0]'
`a' is a rigid type variable bound by
the type signature for tell2 :: a -> String at test.hs:4:10
In the pattern: []
In an equation for `tell2': tell2 [] = "The list is empty"
Now we ask ourselves, what is this does this so-called 'type' construct really mean? When you write tell2 :: a -> String, you are saying is that for any type that is exactly a, tell2 will give us a String. [a] (or [c] or [foo] - the name doesn't matter) is not exactly a. This may seem like an arbitrary distinction, and as far as I know, it is. Let's see what happens when we write
tell2 [] = "The list is empty"
> :t tell2
> tell2 :: [t] -> [Char]
As you well know there is no difference between writing t and a, and [Char] is just a type synonym for String, so the type we wrote and the type GHC infers are identical.
Well, not quite. When you, yourself, the programmer, specify the type of a function manually in your source, the type variables in your type signature become rigid. What does that mean exactly?
from https://research.microsoft.com/en-us/um/people/simonpj/papers/gadt/:
"Instead of "user-specified type", we use the briefer term rigid
type to describe a type that is completely specified, in some
direct fashion, by a programmer-supplied type annotation."
So a rigid type is any type specified by a programmer type signature.
All other types are "wobbly"[1]
So, just by virtue of the fact that you wrote it out, the type signature has become different. And in this new type grammar, we have that a /= [b]. For rigid type signatures, GHC will infer the very least amount of information it can. It must infer that a ~ [b] from the pattern binding; however it cannot make this inference from the type signature you have provided.
Lets look at the error GHC gives for the original function:
test.hs:2:6:
Could not deduce (a ~ [t0])
from the context (Show a)
bound by the type signature for tell :: Show a => a -> String
at test.hs:1:9-29
`a' is a rigid type variable bound by
We see again rigid type variable etc., but in this case GHC also claims it could not deduce something. (By the way - a ~ b === a == b in the type grammar). The type checker is actually looking for a constraint in the type that would make the function valid; it doesn't find it and is nice enough to tell you exactly what it would need to make it valid:
{-# LANGUAGE GADTs #-}
tell :: (a ~ [t0], Show a) => a -> String
tell [] = "The list is empty"
If we insert GHC's suggestion verbatim, it type checks, since now GHC doesn't need to make any inferences; we have told it exactly what a is.
As soon as you pattern match on 'g', eg
pm 'g' = "wow"
your function no longer has a type of (Show a) => a -> String; instead it has has a concrete type for 'a', namely Char, so it becomes Char -> String
This is in direct conflict with the explicit type signature you gave it, which states your function works with any type 'a' (as long as that type is an instance of Show).
You can't pattern match in this case, since you are pattern matching on an Int, Char, etc. But you can use the show function in the Prelude:
pm x = case show x of
"'g'" -> "My favourite Char"
"1" -> "My favourite Int"
_ -> show x
As you may have guessed, show is a bit magical ;). There's actually a whole bunch of show functions implemented for each type that is an instance of the Show typeclass.
tell :: (Show a) =>a->String
This says tell accepts a value of any type a that is showable. You can call it on anything showable. Which implies that inside the implementation of tell, you have to be able to operate on anything at all (that is showable).
You might think that this would be an okay implementation for that type signature:
tell [] = "The list is empty"
Because lists are indeed showable, and so are valid values for the first parameter. But there I'm checking whether the argument is an empty list; only values of the list type can be matched against list patterns (such as the empty list pattern), so this doesn't make sense if I'd called tell 1 or tell True or tell (1, 'c'), etc.
Inside tell, that type a could be any type that is an instance of Show. So the only things I can do with that value are things that are valid to do with all types that are instances of Show. Which basically means you can only pass it to other similar functions with a generic Show a => a parameter.1
Your confusion is stemming from this misconception "Considering that a here is a list and not an element of the list" about the type signature tell :: (Show a) => [a] -> String. Here a is in fact an element of the list, not the list itself.
That type signature reads "tell takes a single paramter, which is a list of some showable type, and returns a string". This version of tell knows it receives a list, so it can do listy things with its argument. It's the things inside the list which are members of some unknown type.
1 Most of those functions will also be unable to do anything with the value other than pass it on to another Show function, but sooner or later the value will either be ignored or passed to one of the actual functions in the Show typeclass; these have specialised implementations for each type so each specialised version gets to know what type it's operating on, which is the only way anything can eventually be done.

Resources