I started learning Haskell and found a nice exercise. It's the following:

```
grouping: Int -> [Student]->[(Team, Student)]
grouping teamNumber = zip ys
where ...
```

So, the exercise wants that i try to fill the rest. The function should do the following: Example : `grouping 2 ['Mark','Hanna','Robert','Mike','Jimmy'] = [(1,'Mark'),(2,'Hanna'),(1,'Robert'),(2,'Mike'),(1,'Jimmy')]`

.

So, we are building teams which consists of two Students, and the last Student 'Jimmy' has no teammates.

Then, I also look up what the predefined function `zip`

does. It gets two list arguments and connects each element of the lists to a tuple to build a list of tuples.

My idea: 1) I try to build two functions "grab" and "infinite". They are looking as following:

```
grap :: Int -> [a] -> [a]
grab _ [] = []
grab n (x:xs) = if n <= 0 then [] else x : grab (n-1) xs
infinite :: Num a => a -> [a]
infinite x = x : infinite(x+1)
```

So, what they do is: With `infinite`

I want to create an infinite list. And `grap`

should take `n`

elements of that. Example `grap 2 (infinite 1) = [1,2]`

.

I use these two in the first line of my *where*-declaration to fulfill the given function from above. So, I have:

```
grouping: Int -> [Student]->[(Team, Student)]
grouping teamNumber = zip ys
where
xs = grap teamNumber (infinite 1)
```

So, `xs`

is now my first list of `zip`

, especially the integer-list.

But now my question: `zip`

as predefined function requires also a second list, especially the list of the names of the students, but in the given function they give zip only one argument, namely the `ys`

as a list. How can I understand that?

# Best How To :

### Type of `grouping teamNumber`

Look carefully at the type of `grouping :: Int -> [Student]->[(Team, Student)]`

, and the arguments that are being declared for its declaration

```
grouping :: Int -> [Student]->[(Team, Student)]
grouping teamNumber = ...
```

What is the return type (the type on the right-hand side of the equals sign) if `grouping`

is provided with all the arguments listed on the left-hand side of the equals sign?

### Answer

The type on the right-hand side of the equals sign is `[Student]->[(Team, Student)]`

. In Haskell, a function that takes two arguments and returns a result can be equivalently seen or defined as a function that takes the first argument and returns a (function that takes the second argument and returns the result). So we could say, for example, that the expression

```
grouping 3 :: [Student]->[(Team, Student)]
```

`(grouping 3)`

is a function that takes a list of students and returns a list of those students, labeled in 3 groups. Presumably, if `(grouping 3)`

were applied to the list of students from your example, we would have

```
(grouping 3) [ 'Mark' , 'Hanna' , 'Robert' , 'Mike' , 'Jimmy' ] =
[(1,'Mark'),(2,'Hanna'),(3,'Robert'),(1,'Mike'),(2,'Jimmy')]
```

### Type of `zip ys`

What does currying have to do with the following type and expression?

```
zip :: [a] -> [b] -> [(a, b)]
zip ys
```

What would the type of `zip ys`

be if, for example, `ys :: [Bool]`

?

What does this have to do with your question?

When you consider this together with the type of `grouping teamNumber`

, how does this tell you what the type of `ys`

needs to be in your exercise?

### Putting it all together

From the exercise code (ignoring the types and the `where`

clause) we have:

```
grouping teamNumber = zip ys
```

Two things can only be `=`

in Haskell if their types will unify. In this case, the type of `grouping teamNumber`

must unify with the type of `zip ys`

.

From the first part, we know that the type of `grouping teamNumber`

is `[Student]->[(Team,Student)]`

.

From the second part, we know that `zip ys`

has the type `[b] -> [(a, b)]`

, where `a`

is a type such that `ys`

has the type `[a]`

.

Therefore, we know that (`~`

is type equality in Haskell)

```
[Student]->[(Team,Student)] ~ [b] -> [(a, b)]
```

These will unify if we substitute the following for the type variables `b`

and `a`

```
b ~ Student
a ~ Team
```

Now, we know the type of `ys`

is `[a]`

, which, if we make the same substitution, is `[Team]`

.

Therefore, the types will be correct if `ys :: [Team]`

.

### Conclusion

If you can provide a `ys :: [Team]`

, you can produce a function from students to students tagged with their team (`[Student]->[(Team,Student)]`

) by passing the `ys`

as the first argument to `zip`

. Such a function is exactly what `grouping`

needs to return when it has been applied to the single argument, `teamNumber :: Int`

.