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

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.

Related

How does these two notations differ in Haskell?

I am new to Haskell and still kind of confused with some notations.
In the function header, i know that
func :: [Int] -> Int
indicates that the input is a list of integers and the output is an integer.
How does this differ from
func :: (Ord a) => [a] -> a
I am asking because they seem to be same, and I wonder why we use different notations for something identical.
The first one is very simple and as you have said, it takes a list of Int and returns a single Int.
The second one, however, can accept many different types for its input (including types you define yourself).
The key is (Ord a). What this is saying is that it has to be a list of orderable types, and if it satisfies that requirement then it is a valid type that can be passed into this particular function.
The Ord typeclass includes the following members:
<
<=
>
>=
So
func :: (Ord a) => [a] -> a
could potentially be a function that takes a list of orderable types and returns the maximum member of that list, as an example. This could be [Int], [Integer], [Float], and many other things.

How are variable names chosen in type signatures inferred by GHC?

When I play with checking types of functions in Haskell with :t, for example like those in my previous question, I tend to get results such as:
Eq a => a -> [a] -> Bool
(Ord a, Num a, Ord a1, Num a1) => a -> a1 -> a
(Num t2, Num t1, Num t, Enum t2, Enum t1, Enum t) => [(t, t1, t2)]
It seems that this is not such a trivial question - how does the Haskell interpreter pick literals to symbolize typeclasses? When would it choose a rather than t? When would it choose a1 rather than b? Is it important from the programmer's point of view?
The names of the type variables aren't significant. The type:
Eq element => element -> [element] -> Bool
Is exactly the same as:
Eq a => a -> [a] -> Bool
Some names are simply easier to read/remember.
Now, how can an inferencer choose the best names for types?
Disclaimer: I'm absolutely not a GHC developer. However I'm working on a type-inferencer for Haskell in my bachelor thesis.
During inferencing the names chosen for the variables aren't probably that readable. In fact they are almost surely something along the lines of _N with N a number or aN with N a number.
This is due to the fact that you often have to "refresh" type variables in order to complete inferencing, so you need a fast way to create new names. And using numbered variables is pretty straightforward for this purpose.
The names displayed when inference is completed can be "pretty printed". The inferencer can rename the variables to use a, b, c and so on instead of _1, _2 etc.
The trick is that most operations have explicit type signatures. Some definitions require to quantify some type variables (class, data and instance for example).
All these names that the user explicitly provides can be used to display the type in a better way.
When inferencing you can somehow keep track of where the fresh type variables came from, in order to be able to rename them with something more sensible when displaying them to the user.
An other option is to refresh variables by adding a number to them. For example a fresh type of return could be Monad m0 => a0 -> m0 a0 (Here we know to use m and a simply because the class definition for Monad uses those names). When inferencing is finished you can get rid of the numbers and obtain the pretty names.
In general the inferencer will try to use names that were explicitly provided through signatures. If such a name was already used it might decide to add a number instead of using a different name (e.g. use b1 instead of c if b was already bound).
There are probably some other ad hoc rules. For example the fact that tuple elements have like t, t1, t2, t3 etc. is probably something done with a custom rule. In fact t doesn't appear in the signature for (,,) for example.
How does GHCi pick names for type variables? explains how many of these variable names come about. As Ganesh Sittampalam pointed out in a comment, something strange seems to be happening with arithmetic sequences. Both the Haskell 98 report and the Haskell 2010 report indicate that
[e1..] = enumFrom e1
GHCi, however, gives the following:
Prelude> :t [undefined..]
[undefined..] :: Enum t => [t]
Prelude> :t enumFrom undefined
enumFrom undefined :: Enum a => [a]
This makes it clear that the weird behavior has nothing to do with the Enum class itself, but rather comes in from some stage in translating the syntactic sequence to the enumFrom form. I wondered if maybe GHC wasn't really using that translation, but it really is:
{-# LANGUAGE NoMonomorphismRestriction #-}
module X (aoeu,htns) where
aoeu = [undefined..]
htns = enumFrom undefined
compiled using ghc -ddump-simpl enumlit.hs gives
X.htns :: forall a_aiD. GHC.Enum.Enum a_aiD => [a_aiD]
[GblId, Arity=1]
X.htns =
\ (# a_aiG) ($dEnum_aiH :: GHC.Enum.Enum a_aiG) ->
GHC.Enum.enumFrom # a_aiG $dEnum_aiH (GHC.Err.undefined # a_aiG)
X.aoeu :: forall t_aiS. GHC.Enum.Enum t_aiS => [t_aiS]
[GblId, Arity=1]
X.aoeu =
\ (# t_aiV) ($dEnum_aiW :: GHC.Enum.Enum t_aiV) ->
GHC.Enum.enumFrom # t_aiV $dEnum_aiW (GHC.Err.undefined # t_aiV)
so the only difference between these two representations is the assigned type variable name. I don't know enough about how GHC works to know where that t comes from, but at least I've narrowed it down!
Ørjan Johansen has noted in a comment that something similar seems to happen with function definitions and lambda abstractions.
Prelude> :t \x -> x
\x -> x :: t -> t
but
Prelude> :t map (\x->x) $ undefined
map (\x->x) $ undefined :: [b]
In the latter case, the type b comes from an explicit type signature given to map.
Are you familiar with the concepts of alpha equivalence and alpha substitution? This captures the notion that, for example, both of the following are completely equivalent and interconvertible (in certain circumstances) even though they differ:
\x -> (x, x)
\y -> (y, y)
The same concept can be extended to the level of types and type variables (see "System F" for further reading). Haskell in fact has a notion of "lambdas at the type level" for binding type variables, but it's hard to see because they're implicit by default. However, you can make them explicit by using the ExplicitForAll extension, and play around with explicitly binding your type variables:
ghci> :set -XExplicitForAll
ghci> let f x = x; f :: forall a. a -> a
In the second line, I use the forall keyword to introduce a new type variable, which is then used in a type.
In other words, it doesn't matter whether you choose a or t in your example, as long as the type expressions satisfy alpha-equivalence. Choosing type variable names so as to maximize human convenience is an entirely different topic, and probably far more complicated!

Are type synonyms with typeclass constraints possible?

Feel free to change the title, I'm just not experienced enough to know what's really going on.
So, I was writing a program loosely based on this, and wrote this (as it is in the original)
type Row a = [a]
type Matrix a = [Row a]
Nothing special there.
However, I found myself writing a couple of functions with a type like this:
Eq a => Row a -> ...
So I thought that perhaps I could write this constraint into the type synonym definition, because to my mind it shouldn't be that much more complicated, right? If the compiler can work with this in functions, it should work as a type synonym. There are no partial applications here or anything or some kind of trickery (to my eyes).
So I tried this:
type Row a = Eq a => [a]
This doesn't work, and the compiler suggested switching on RankNTypes. The option made it compile, but the functions still required that I leave the Eq a => in their type declarations. As an aside, if I tried also having a type synonym like type Matrix a = [Row a] like before, it results in an error.
So my question(s) are thus:
Is it possible to have a type synonym with a typeclass constraint in its definition?
If not, why?
Is the goal behind this question achievable in some other way?
Constraints on a type variable can not be part of any Haskell type signature.
This may seem a bit of a ridiculous statement: "what's (==) :: Eq a => a -> a -> a then?"
The answer is that a doesn't really exist, in much the same way there is not really an x in the definition f x = x * log x. You've sure enough used the x symbol in defining that function, but really it was just a local tool used in the lambda-abstraction. There is absolutely no way to access this symbol from the outside, indeed it's not required that the compiler even generates anything corresponding to x in the machine code – it might just get optimised away.
Indeed, any polymorphic signature can basically be read as a lambda expression accepting a type variable; various writing styles:
(==) :: forall a . Eq a => a -> a -> a
(==) :: ∀ a . Eq a => a -> a -> a
(==) :: Λa. {Eq a} -> a -> a -> a
This is called System F.
Note that there is not really a "constraint" in this signature, but an extra argument: the Eq-class dictionary.
Usually you want to avoid having constraints in your type synonyms unless it's really necessary. Take the Data.Set API from containers for example.
Many operations in Data.Set require the elements of the set to be instances of Ord because Set is implemented internally as a binary tree. member or insert both require Ord
member :: Ord a => a -> Set a -> Bool
insert :: Ord a => a -> Set a -> Set a
However the definition of Set doesn't mention Ord at all.
This is because some operations on Set dont require an Ord instance, like size or null.
size :: Set a -> Int
null :: Set a -> Bool
If the type class constraint was part of the definition of Set, these functions would have to include the constraint, even though it's not necessary.
So yes, it is possible to have constraints in type synonyms using RankNTypes, but it's generally ill-advised. It's better to write the constraint for the functions that need them instead.

How to Interpret (Eq a)

I need to create a function of two parameters, an Int and a [Int], that returns a new [Int] with all occurrences of the first parameter removed.
I can create the function easily enough, both with list comprehension and list recursion. However, I do it with these parameters:
deleteAll_list_comp :: Integer -> [Integer] -> [Integer]
deleteAll_list_rec :: (Integer -> Bool) -> [Integer] -> [Integer]
For my assignment, however, my required parameters are
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_rec :: (Eq a) => a -> [a] -> [a]
I don't know how to read this syntax. As Google has told me, (Eq a) merely explains to Haskell that a is a type that is comparable. However, I don't understand the point of this as all Ints are naturally comparable. How do I go about interpreting and implementing the methods using these parameters? What I mean is, what exactly are the parameters to begin with?
#groovy #pelotom
Thanks, this makes it very clear. I understand now that really it is only asking for two parameters as opposed to three. However, I still am running into a problem with this code.
deleteAll_list_rec :: (Eq a) => a -> [a] -> [a]
delete_list_rec toDelete [] = []
delete_list_rec toDelete (a:as) =
if(toDelete == a) then delete_list_rec toDelete as
else a:(delete_list_rec toDelete as)
This gives me a "The type signature for deleteAll_list_rec
lacks an accompanying binding" which makes no sense to me seeing as how I did bind the requirements properly, didn't I? From my small experience, (a:as) counts as a list while extracting the first element from it. Why does this generate an error but
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_comp toDelete ls = [x | x <- ls, toDelete==x]
does not?
2/7/13 Update: For all those who might stumble upon this post in the future with the same question, I've found some good information about Haskell in general, and my question specifically, at this link : http://learnyouahaskell.com/types-and-typeclasses
"Interesting. We see a new thing here, the => symbol. Everything before the => symbol is >called a class constraint. We can read the previous type declaration like this: the >equality function takes any two values that are of the same type and returns a Bool. The >type of those two values must be a member of the Eq class (this was the class constraint).
The Eq typeclass provides an interface for testing for equality. Any type where it makes >sense to test for equality between two values of that type should be a member of the Eq >class. All standard Haskell types except for IO (the type for dealing with input and >output) and functions are a part of the Eq typeclass."
One way to think of the parameters could be:
(Eq a) => a -> [a] -> [a]
(Eq a) => means any a's in the function parameters should be members of the
class Eq, which can be evaluated as equal or unequal.*
a -> [a] means the function will have two parameters: (1) an element of
type a, and (2) a list of elements of the same type a (we know that
type a in this case should be a member of class Eq, such as Num or
String).
-> [a] means the function will return a list of elements of the same
type a; and the assignment states that this returned list should
exclude any elements that equal the first function parameter,
toDelete.
(* edited based on pelotom's comment)
What you implemented (rather, what you think you implemented) is a function that works only on lists of Integers, what the assignment wants you to do is create one that works on lists of all types provided they are equality-comparable (so that your function will also work on lists of booleans or strings). You probably don't have to change a lot: Try removing the explicit type signatures from your code and ask ghci about the type that it would infer from your code (:l yourfile.hs and then :t deleteAll_list_comp). Unless you use arithmetic operations or similar things, you will most likely find that your functions already work for all Eq a.
As a simpler example that may explain the concept: Let's say we want to write a function isequal that checks for equality (slightly useless, but hey):
isequal :: Integer -> Integer -> Bool
isequal a b = (a == b)
This is a perfectly fine definition of isequal, but the type constraints that I have manually put on it are way stronger than they have to. In fact, in the absence of the manual type signature, ghci infers:
Prelude> :t isequal
isequal :: Eq a => a -> a -> Bool
which tells us that the function will work for all input types, as long as they are deriving Eq, which means nothing more than having a proper == relation defined on them.
There is still a problem with your _rec function though, since it should do the same thing as your _comp function, the type signatures should match.

Haskell typing for Int's and Double's

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."

Resources