What is the value of the type? - haskell

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.

Related

Strange behavior of type parameters in "type" versus "newtype": is this a bug or a feature?

I'm writing a typeclass to add type reflection to Haskell data types. Part of it looks like this:
type VarName a = Text
class Reflective a where
-- | A reflective type may have a fixed name, or it may be a union
-- where each variant has a distinct name.
reflectiveName :: a -> VarName a
-- | One default value of the type for each reflective name.
reflectiveDefaults :: [a]
The idea is that if I write
data ExampleType = Foo Int | Bar String
then in the Reflective instance reflectiveName will return either "Foo" or "Bar" as appropriate, and reflectiveDefaults will return [Foo 0, Bar ""]
So now I can write a function to give me all the names of the variants:
reflectiveNames :: (Reflective a) => [VarName a]
reflectiveNames = map reflectiveName reflectiveDefaults
and I can call it like this:
exampleNames = reflectiveNames :: [VarName ExampleType]
When I compile this I get the following error in the type declaration for reflectiveNames:
• Could not deduce (Reflective a0)
from the context: Reflective a
bound by the type signature for:
reflectiveNames :: Reflective a => [VarName a]
The type variable ‘a0’ is ambiguous
However if I replace the VarName with a newtype:
newtype VarName a = VarName Text
then it works.
Is this a feature of the Haskell type system, or is it a bug in GHC? And if the former, why is it inventing a new type variable a0?
Why this fails for a type...
If you write type then you do not construct a new type, you construct an alias. So you defined:
type VarName a = Text
Hence now each time you write VarName SomeType, you have basically written Text. So VarName Char ~ VarName Int ~ Text (the tilde ~ means that the two types are equal).
Type aliases are useful however since they typically minimize the code (frequently the name of the alias is shorter than its counterpart), it reduces the complexity of signatures (one does not have to remember a large hierarchy of types), and finally it can be used if some types are not yet fully decided (for example time can be modelled as an Int32, Int64, etc.) and we want to define some placeholder to easily change a large number of signatures.
But the point is that each time you write a VarName Char for example, Haskell will replace this with Text. So now if we take a look at your function, you have written:
reflectiveNames :: Reflective a => [Text]
reflectiveNames = map reflectiveName reflectiveDefaults
Now there is a problem with this function: there is a type variable a (in Reflective a), but nowhere in the signature do we use this type parameter. The problem is that Haskell does not know what a to fill in in case you call this function, and that is a real problem (here), since the semantics of reflectiveName and reflectiveDefaults can be completely different for an a ~ Char, then for an a ~ Int. The compiler can not just "pick" a type for a, since that would mean that two different Haskell compilers, could end up with functions that generate different output, and thus a different program (usually one of the fundamental desired aspects of a programming language is unambiguity, the fact that there are no two semantically different programs that map on the same source code).
... and why it works for a newtype
Now why doesn't this happen if we use newtype? Basically a newtype is the same as a data declaration, except for some small details: behind the curtains for example, Haskell will not produce such constructor, it will simply store the value that is wrapped inside the constructor but it will see the value as a different type. The newtype definition
newtype VarName a = VarName Text
is thus (conceptually) almost equivalent to:
data VarName a = VarName Text
Although Haskell will (given it is a compiler that can deal with such optimization) factor the constructor away, we can conceptually assume that it is there.
But the main difference is that we did not define a type signature: we defined a new type, so the function signature stays:
reflectiveNames :: Reflective a => [VarName a]
reflectiveNames = map reflectiveName reflectiveDefaults
and we can not just write Text instead of VarName a, since a Text is not a VarName a. It also means that Haskell can perfectly derive what a is. If we would for instance trigger reflectiveNames :: [VarName Char], then it know that a is a Char, and it will thus use the instance of Reflective for a ~ Char. There is no ambiguity. Of course we can define aliasses like:
type Foo = VarName Char -- a ~ Char
type Bar b = VarName Int -- a ~ Int
But then still a is resolved to Char and Int respectively. Since this is a new type, we will always carry the type of a through the code, and hence the code is unambiguous.

Invalid data type

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

Does the Either type constructor contain a phantom type each for the left/right case?

AFAIK, only types are inhabited by values in Haskell, not type constructors. Either is a binary type constructor of kind * -> * -> *. Left and Right both apply this type constructor to a single type, which is provided by the passed value. Doesn't that mean that in both cases Either is merely partially applied and thus still a type constructor awaiting the missing type argument?
let x = Right 'x' -- Either a Char
x has the type Either a Char. I would assume that this type would have the kind * -> *. This is clearly a polymorphic type, not a ground one. Yet Either a Char can be inhabited by values like 'x'.
My suspicion is that the type variable a is a phantom type for the Right case resp. b for Left. I know phantom types in connection with Const, where the respective type variable isn't used at all. Am I on the right tack?
AFAIK, only types are inhabited by values in Haskell, not type constructors.
Spot on.
Left and Right both apply this type constructor to a single type
You can't say that. Left and Right don't live in the type language at all, so they don't apply anything to any types, they only apply themselves to values.
x has the type Either a Char. I would assume that this type would have the kind * -> *
You need to distinguish between function/constructor arguments, and type variables. It's basically the distinction between free and bound variables. Either a Char still has kind *, not * -> *, because it is already applied to a. Yes, that's a type variable, but it still is an argument that's already applied.
Yet Either a Char can be inhabited by values like 'x'.
Not quite – it can be inhabited by values like Right 'x'.
My suspicion is that the type variable a is a phantom type for the Right case resp. b for Left
kind of, but I wouldn't call it “phantom” because you can't just count out Left or Right. At least not unless you choose Either Void b, but in that case you don't have the a variable.
I would argue that a type variable is phantom if and only if the choice of the type variable does not restrict what values can be passed to the type's constructors. The important part is that this is a type-centric definition. It is determined by looking only at the type definition, not at some particular value of the type.
So does it matter that no value of type String appears in the value Left 5 :: Either Int String? Not at all. What matters is that the choice of String in Either Int String prevents Right () from type-checking.
Haskell has "implicit universal quantification", which means that type variables have an implicit forall. Either a Int is equivalent to forall a. Either a Int.
One way to consider a forall is that it's like a lambda, but for type variables. If we use the syntax # for type application, then, you can "apply" a type to this and get a new type out.
let foo = Right 1 :: forall a. Either a Int
foo #Char :: Either Char Int
foo #Double :: Either Double Int

New type declaring functions?

I'm familiar with the newtype declaration:
newtype MyAge = Age {age :: Int} deriving (Show, Eq, Ord)
In this instance Age is an Int, however I've come across the code below and I can't understand it:
newtype Ages a = Ages {age :: String -> [(a,String)]}
This appears to be a function declaration? (takes string, returns list of tuples containing 'a' and string) - is this correct?
N.B I've just realized this is just basic record syntax to declare a function.
Additionally, I've tried to implement this type, but I must be doing something wrong:
newtype Example a = Example {ex :: Int -> Int}
myexample = Example {ex = (\x -> x + 1)}
This compiles, however I don't understand why as I haven't passed the 'a' parameter?
This appears to be a function declaration?
Yes. Specifically, String -> [(a,String)] is a function type. A newtype declaration is analogous to a simple wrapper around any given type. There's no restriction that says you can't make it based on a function type, and it works in exactly the same way.
Also remember that you can always replace newtype with data; in this case, thinking about the resulting type as a record type that has a field that is a function might be helpful; newtype is just a special, optimized case.
One other thing to mention is that your two lines also differ in that the second one is parametrized over a. This can of course be used with regular types:
newtype MyWrapper a = MyWrapper a
or a function type can be newtype-d without parametrisation
newtype MyFunction = MyFunction (Float -> Float)
You can also write the above using the record syntax that gives you the "getter" function as well.

Haskell type inference with Read

I think I have a problem with Haskell type inference.
I made my own data type and made it instance of the class Read. My data type is actually take an other type as parameter, it's a type parameter.
I redefined readPresc in a way that parse the string and give back my new data. When I write:
read "string that represent MyType a" :: MyType a
it works perfectly fine (at least it does what I expected)
Now I have a function, let's call it insert, that takes an element of type a, MyType a, and gives back a new MyTape a.
insert :: a -> MyType a -> a
but when I write:
insert 3 "string that rapresent MyType Int"
I got Ambigous type.
How can I tell haskell to infer to the read the same type that is the parameter of the insert?
How can I tell haskell to infer to the read the same type that is the parameter of the insert?
You don't need to, that is inferred from the type of insert.
The problem is that in
insert 3 (read "string that rapresent MyType Int" )
(I inserted the read for it to be possibly type correct), the literal 3 is polymorphic. Its type is
3 :: Num a => a
so that is still not enough information to determine what type read should produce, hence the error.
You need to provide the necessary information, for example
insert (3 :: Int) (read "string that rapresent MyType Int" )
or by using the result in a context that determines the type variable a.

Resources