What does => mean in a type signature?

I am just starting to teach you Haskell, and I saw that this is used in the example without explanation:

tell :: (Show a) => [a] -> String 

What does this mean, in particular, => ? I know that this will not work if I submenu -> or delete it, but I really do not understand why.

+5
source share
3 answers

This is a type restriction, so a must be an instance of the Show class.

see for example here

+6
source

Here is another way to look at it. Some function arguments are invisible, others are visible. The type input -> output tells us that a visible input is expected as an argument. Type (Constraint) => output tells us that some invisible information is expected. They are not interchangeable because visible arguments must be written, and invisible arguments must not be written. The invisible arguments are that the compiler must understand it (well, it sounds like me), and he insists on puzzling them: he refuses to just say what they are!

In secret, the full type of this tell example is

 tell :: forall (a :: *). (Show a) => [a] -> String 

What I did was to indicate where this variable a goes and what this thing is. You can also read this as a "deal": tell offers to work for all types of a that satisfy the request (Show a) .

There are three things that make sense to tell . Two of them are invisible, and one of them is visible. That is, when you use tell , you make the visible argument explicit, and the compiler tries to fill in the invisible parts. Let work through this type more slowly.

 tell :: forall (a :: *). -- the type of elements to tell (invisible) (Show a) => -- how to make a String from one element (invisible) [a] -> -- the list of elements to be told (visible) String -- the String made by showing all the elements 

So, when you use tell , for example,

 tell [True, False] 

you specify only a visible argument: a list of [True, False] things to tell, and the compiler calculates invisible arguments. He knows that True and False are both values ​​of type Bool , therefore means

 [True, False] :: [Bool] 

how the compiler determines that a in the type tell must be Bool , making [a] = [Bool]

(By the way, near [True, False] :: [Bool] . On the left side :: square brackets [..], enter the list values. Right :: square brackets, [..], enter the list type. They may just look black on a gray background for you, but my brain colors the colored square brackets in red and the fonts in blue. They are completely different. I'm sorry that I can’t draw the code on this site.

So, now another invisible argument should satisfy this thing (Show a) , which we now know specifically (Show Bool) , because we found out that a is Bool . We call this part of the type “restriction”, but in fact this requirement is not only about the truth of the fact, but also that there is some useful material. The material required here is that there is a function

 show :: Bool -> String 

This function is used to convert individual True and False elements to String during the tell [True, False] evaluation process.

Show is the name of the type class, and show is the class method of this type. The class type indicates the operation interface that should be implemented for each instance . An invisible argument to a function is a record (or "dictionary") that packs implementations of these operations for the type in question (here is the implementation of Show ). Without this information, the compiled code will not be able to do its job, but we do not need to write this information, because the compiler can (at least in this case) search through instances of which it knows, and fill them out alone for work.

So, we have not just arguments of an invisible type (which are displayed at compile time and then deleted before runtime), they are signaled by variables of the lower case type or more explicitly - forall blah . . We also have invisible implementations of class type operations (which are scanned at compile time to provide vital runtime information). So, something very important happens between type inference and deletion: while the compiler still knows the types, it uses them to find out what invisible implementations are needed at runtime so that we can leave without writing them down ourselves.

The reduction, => in type documents is our expectation that the compiler will use type information to generate runtime code that we do not need to write. This is a good win, right there.

Street motive for type system hackers. The message that the invisible visible difference is in another place from the erased useful difference is that some people have not yet received. This is Hindley-Milner's classic position, but the fact is that these differences are orthogonal, and the sooner people learn to enjoy it, the better.

+22
source

=> first introduced and explained in Chapter 3 - Types and Typeclasses :

What is a function type signature ==?

 ghci> :t (==) (==) :: (Eq a) => a -> a -> Bool 

Note: the equality operator == is a function. So, +, *, -, / and almost all operators. If the function consists only of special characters, he considered the default infix function. If we want to check its type, pass it to another function, or name it as a prefix, we must surround it in parentheses.

Interesting. Here we see a new thing, the symbol =>. Everything up to the symbol => is called a class. We can read the previous types: the equality function takes any two values ​​that have the same type and return Bool. The type of these two values ​​must be members of the Eq class (it was a class constraint).

+7
source

Source: https://habr.com/ru/post/1233067/


All Articles