Invalid data type - haskell

The following code is invalid:
data A = Int | [Int] | (Int, Int)
Why is it ok to use the concrete type Int as part of a data type definition, but not the concrete type [Int] or (Int, Int)?

Why is it ok to use the concrete type Int as part of a data type definition (..)
It is not OK.
What you here have written is the definition of a data type A that has a constructor named Int. This has nothing to do with the data type Int, it is simply a coincidence that the name of the constructor is the same as the name of a type, but that is not a problem for the Haskell compiler, since Haskell has a clear distinction between types and constructor names.
You can not use [Int] however, since [Int] is not an identifier (it starts with an open square bracket), nor is it an operator (that can only use symbols). So Haskell does not really knows how to deal with this and errors on this input.
If you want to define a datatype that can take an Int value, you need to add it as a parameter. You can also define constructors for your [Int] and (Int, Int) parameters. For instance:
data A = Int Int | Ints [Int] | Int2 (Int,Int)
So here there are three constructors: Int, Ints, and Int2. And the first constructor takes an Int as parameter, the second one an [Int], and the last one an (Int, Int).
That being said, this will probably result into a lot of confusion, so it is better to use constructor names that cause less confusion, for instance:
data A = A Int | As [Int] | A2 (Int,Int)
Note that the A of data A can be used in the signature of the functions, whereas the constructors (in boldcase) are used as values (so in the implementation of the function, that is the pattern matching in the head of the clauses, and in order to construct a value in the body of the clauses).

Related

Defining new types in Haskell

I am pretty new to Haskell, and I was wondering if one can define new types that are defined by lists of other types. For example, I assume a string is defined as a list of characters, so can I define a vector as a list of force values (in this case floating point values)?
If so, how can I declare and use this?
data Vector = Vector [Float]
Is this enough to define the new type and the constructor for it? Can I simply call
x = Vector [2.4,2.5,2.7] for example?
I'm using ghci, if that makes any difference
Yes - data TypeName = TypeConstructor Type1 Type2 ... TypeN just creates a function TypeConstructor :: Type1 -> Type2 -> ... -> TypeN -> TypeName, and there is special syntactic sugar for lists so that what would normally have to be something like List Float to instead be [Float].
So data Vector = Vector [Float] creates a function Vector :: [Float] -> Vector (note that the function and the result type are different things that happen to share a name).
The Vector function is called a type constructor, and type constructors are the only functions that can have initial capital letters in their name.

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:

What is the value of the type?

I have following type declaration:
data MyType = MyVal Int deriving (Eq, Show)
As you can see, it has only one data type constructor with an argument.
In the book, it says:
Because MyVal has one Int argument, a value of type MyType must
contain one — only one — Int value
Why is Int a value of type MyType or what does it mean?
It doesn't say that Int is of type MyType, it says that MyVal (constructor) must only contain an Int, so for example you can not do MyVal "hey!"
Check this
Prelude> data MyType = MyVal Int deriving (Eq, Show)
Prelude> :t MyVal 9
MyVal 9 :: MyType
Prelude> MyVal '9'
<interactive>:12:7: error:
• Couldn't match expected type ‘Int’ with actual type ‘Char’
• In the first argument of ‘MyVal’, namely ‘'9'’
In the expression: MyVal '9'
In an equation for ‘it’: it = MyVal '9'
As you can see, the only way of using MyVal wich is of type MyType is with an Int, so no other type is allowed.
To be super-explicit and clear, which is hopefully helpful: you said that "As you can see, it has only one data type constructor with an argument.", but I would adjust that slightly.
data MyType = MyVal Int deriving (Eq, Show)
Here MyType is the type. It's a type constructor with zero arguments, is one way of viewing it. Or, you could say it's the data type constructor.
However, MyVal is a value constructor. It's one of MyType data type's value constructors (which there are only one of in this example). That is, it's actually a function that constructs values of type MyType. So, MyType has one value constructor called MyVal that takes one argument. That argument has type Int.
If we ask GHCi what the type of this function is, it's clear its one argument is of type Int:
Main> :t MyVal
MyVal :: Int -> MyType
Why is it useful to "wrap" the type Int when it's already a type? One reason is that it separates the meaning of MyVal from Int, and you can thus have your own type, which is distinct from Int according to the type checker and your code, even though its representation happens to be an Int for now.
Maybe tomorrow you may decide to change it to an Integer, in which case all you probably have to do is change that one spot, and the rest of your code will work (assuming you don't use Int to refer to your unwrapped MyVals, and that you have data access functions to deal with the base operations on the internal value of MyVal).
As an aside, just FYI, wrapping a single type in a data declaration like this is usually not done in professional code because it costs execution cycles to wrap and unwrap it. There's another way of declaring single-value types such as this, called newtype which gives a cost-free (at runtime) way to explain to the compiler and typechecker that you want a distinct value that has a representation as one of the existing values. I'm sure whatever book you're reading will explain this in due course, but if it doesn't, make a note to look these up later.

haskell - Cannot parse data constructor in a data/newtype declaration: [Either Int Int]

I'm trying to declare a datatype that is a list of Either types.
data EitherInts = [Either Int Int]
But when I try to compile this type I get an error:
Cannot parse data constructor in a data/newtype declaration: [Either Int Int]
I have no idea why. What am I doing wrong?
data is for defining new algebraic data types, which must each have their own constructor(s). So you could write
data EitherInts = EitherInts [Either Int Int]
But you probably don't mean this: you want some kind of type synonym. There are two possibilities:
type EitherIntsType = [Either Int Int]
or
newtype EitherIntsNewtype = EitherInts [Either Int Int]
The first, using type, acts exactly like [Either Int Int]: a value such as [Left 2] is a valid value of the new EitherIntsType type. It's just a new, abbreviated name for that existing type, and can be used interchangeably with it. This approach is fine when you just want to be able to use a different name for an existing type: for clarity, or to give a shorter name to a much longer type.
The second, using newtype, is more heavy-weight. It acts more like data, with its own constructor. Values like [Left 2] are not valid values of the new EitherIntsNewtype type. Instead, you must write EitherintsNewtype [Left 2] to lift an existing list value, and you must pattern-match to extract values. This approach is better when you want the compiler's help making sure you don't mix up lifted and unlifted values, or when you want something like an existing type but with different typeclass instances (because you can give your newtype its own typeclass instances, which a type can't have).

Making a type polymorphic

So i'm defining a type which a list of tuples basically and I can't work out how to make it polymorphic.
so far i've got
module ListTup where
type ListTup = [(Char, String)]
and I was wondering if it was possible to make it so that the Char part could be anything e.i String, int what ever.
Is it possible?
I tried to use the Maybe Type but it throw a ton of errors my way
You can include type variables when defining type synonyms, like so:
type ListTup a = [(a, String)].
It depends on what you want to do. If you want different lists each of which will have the same type in the tuple's first element, you can parametrise the type constructor, like C.Quilley suggested above.
If you want each of your lists to be able to have different types, you can box all required types in an algebraic type (discriminated union):
data MyKey = MyCharKey Char | MyStringKey String | MyIntKey Int
type ListTup = [(MyKey, String)]
You cannot have "whatever", because the types need to be decidable at compilation time.

Resources