Haskell taking in two list with a int and returning a tuple - haskell

I am trying to learn haskell and saw a exercise which says
Write two different Haskell functions having the same type:
[a] -> [b] -> Int -> (a,b)
So from my understanding the expressions should take in two lists, an int and return a tuple of the type of the lists.
What i tried so far was
together :: [a] -> [b] -> Int -> (a,b)
together [] [] 0 = (0,0)
together [b] [a] x = if x == a | b then (b,a) else (0,0)
I know I am way off but any help is appreciated!

First you need to make your mind up what the function should return. That is partly determined by the signature. But still you can come up with a lot of functions that return different things, but have the same signature.
Here one of the most straightforward functions is probably to return the elements that are placed on the index determined by the third parameter.
It makes no sense to return (0,0), since a and b are not per se numerical types. Furthermore if x == a | b is not semantically valid. You can write this as x == a || x == b, but this will not work, since a and b are not per se Ints.
We can implement a function that returns the heads of the two lists in case the index is 0. In case the index is negative, or at least one of the two lists is exhausted, then we can raise an error. I leave it as an exercise what to do in case the index is greater than 0:
together :: [a] -> [b] -> Int -> (a,b)
together [] _ = error "List exhausted"
together _ [] = error "List exhausted"
together (a:_) (b:_) 0 = (a, b)
together (a:_) (b:_) n | n < 0 = error "Negative index!"
| …
you thus still need to fill in the ….

I generally dislike those "write any function with this signature"-type excercises precisely because of how arbitrary they are. You're supposed to figure out a definition that would make sense for that particular signature and implement it. In a lot of cases, you can wing it by ignoring as many arguments as possible:
fa :: [a] -> [b] -> Int -> (a,b)
fa (a:_) (b:_) _ = (a,b)
fa _ _ _ = error "Unfortunately, this function can't be made total because lists can be empty"
The error here is the important bit to note. You attempted to go around that problem by returning 0s, but this will only work when 0 is a valid value for types of a and b. Your next idea could be some sort of a "Default" value, but not every type has such a concept. The key observation is that without any knowledge about a type, in order to produce a value from a function, you need to get this value from somewhere else first*.
If you actually wanted a more sensible definition, you'd need to think up a use for that Int parameter; maybe it's the nth element from each
list? With the help of take :: Int -> [a] -> [a] and head :: [a] -> a this should be doable as an excercise.
Again, your idea of comparing x with a won't work for all types; not every type is comparable with an Int. You might think that this would make generic functions awfully limited; that's the point where you typically learn about how to express certain expectations about the types you get, which will allow you to operate only on certain subsets of all possible types.
* That's also the reason why id :: a -> a has only one possible implementation.

Write two different Haskell functions having the same type:
[a] -> [b] -> Int -> (a,b)
As Willem and Bartek have pointed out, there's a lot of gibberish functions that have this type.
Bartek took the approach of picking two based on what the simplest functions with that type could look like. One was a function that did nothing but throw an error. And one was picking the first element of each list, hoping they were not empty and failing otherwise. This is a somewhat theoretical approach, since you probably don't ever want to use those functions in practice.
Willem took the approach of suggesting an actually useful function with that type and proceeded to explore how to exhaust the possible patterns of such a function: For lists, match the empty list [] and the non-empty list a:_, and for integers, match some stopping point, 0 and some categories n < 0 and ….
A question that arises to me is if there is any other equally useful function with this type signature, or if a second function would necessarily have to be hypothetically constructed. It would seem natural that the Int argument has some relation to the positions of elements in [a] and [b], since they are also integers, especially because a pair of single (a,b) is returned.
But the only remotely useful functions (in the sense of not being completely silly) that I can think of are small variations of this: For example, the Int could be the position from the end rather than from the beginning, or if there's not enough elements in one of the lists, it could default to the last element of a list rather than an error. Neither of these are very pleasing to make ("from the end" conflicts with the list being potentially infinite, and having a fall-back to the last element of a list conflicts with the fact that lists don't necessarily have a last element), so it is tempting to go with Bartek's approach of writing the simplest useless function as the second one.

Related

The meaning of the universal quantification

I am trying to understand the meaning of the universal quantification from the following page http://dev.stephendiehl.com/hask/#universal-quantification.
I am not sure, if I understand this sentence correctly
The essence of universal quantification is that we can express
functions which operate the same way for a set of types and whose
function behavior is entirely determined only by the behavior of all
types in this span.
Let`s take the function from the example:
-- ∀a. [a]
example1 :: forall a. [a]
example1 = []
What I can do with the function example1 is, to use every functions, that is defined for List type.
But I did not get the exactly purpose of the universal quantification in Haskell.
I need a collection of numbers, and I need to be able to easily insert into the middle of the list, so I decide on making a linked list. Being a savvy Hask-- programmer (Hask-- being the variant of Haskell that does not have universal quantification!), I quickly whip up a type and a length function without trouble:
data IntLinkedList = IntNil | IntCons Int IntLinkedList
length_IntLinkedList :: IntLinkedList -> Int
length_IntLinkedList IntNil = 0
length_IntLinkedList (IntCons _ tail) = 1 + length_IntLinkedList tail
Later I realize it would be handy to have a variant type that can store numbers not quite as big as 1 and not quite as small as 0. No problem...
data FloatLinkedList = FloatNil | FloatCons Float FloatLinkedList
length_FloatLinkedList :: FloatLinkedList -> Int
length_FloatLinkedList FloatNil = 0
length_FloatLinkedList (FloatCons _ tail) = 1 + length_FloatLinkedList tail
Boy that code looks awfully familiar! And if, later, I discover it would be nice to have a variant that can store Strings I am once again left copying and pasting the exact same code, and tweaking the exact same places that are specific to the contained type. Wouldn't it be nice if there were a way to just cook up a linked list once and for all that could contain elements of any single type, and a length function that worked uniformly no matter what elements it had? After all, our length functions above didn't even care what values the elements had. In Haskell, this is exactly what universal quantification gives you: a way to write a single function which works with an entire collection of types.
Here's how it looks:
data LinkedList a = Nil | Cons a (LinkedList a)
length_LinkedList :: forall a. LinkedList a -> Int
length_LinkedList Nil = 0
length_LinkedList (Cons _ tail) = 1 + length_LinkedList tail
The forall says that this function for all variants of linked lists -- linked lists of Ints, linked lists of Floats, linked lists of Strings, linked lists of functions that take FibbledyGibbets and return linked lists of tuples of Grazbars and WonkyNobbers, ...
How nice! Now instead of separate IntLinkedList and FloatLinkedList types, we can just use LinkedList Int and LinkedList Float for that, and length_LinkedList, implemented once, works for both.

Type variables in function signature

If I do the following
functionS (x,y) = y
:t functionS
functionS :: (a, b) -> b
Now with this function:
functionC x y = if (x > y) then True else False
:t function
I would expect to get:
functionC :: (Ord a, Ord b) => a -> b -> Bool
But I get:
functionC :: Ord a => a -> a -> Bool
GHCI seems to be ok with the 2 previous results, but why does it give me the second? Why the type variable a AND b aren't defined?
I think you might be misreading type signatures. Through no fault of your own––the examples you using to inform your thinking are kind of confusing. In particular, in your tuple example
functionS :: (a,b) -> b
functionS (x,y) = y
The notation (_,_) means two different things. In the first line, (a,b) refers to a type, the type of pairs whose first element has type a and second has type b. In the second line, (x,y) refers to a specfiic pair, where x has type a and y has type b. While this "pun" provides a useful mnemonic, it can be confusing as you are first getting the hang of it. I would rather that the type of pairs be a regular type constructor:
functionS :: Pair a b -> b
functionS (x,y) = y
So, moving on to your question. In the signature you are given
functionC :: Ord a => a -> a -> Bool
a is a type. Ord a says that elements of the type a are orderable with respect to each other. The function takes two arguments of the same type. Some types that are orderable are Integer (numerically), String (lexicographically), and a bunch of others. That means that you can tell which of two Integers is the smaller, or which of two Strings are the smaller. However we don't necessarily know how to tell whether an Integer is smaller than a String (and this is good! Have you seen what kinds of shenanigans javascript has to do to support untyped equality? Haskell doesn't have to solve this problem at all!). So that's what this signature is saying –– there is only one single orderable type, a, and the function takes two elements of this same type.
You might still be wondering why functionS's signature has two different type variables. It's because there is no constraint confining them to be the same, such as having to order them against each other. functionS works equally well with a pair where both components are integers as when one is an integer and the other is a string. It doesn't matter. And Haskell always picks the most general type that works. So if they are not forced to be the same, they will be different.
There are more technical ways to explain all this, but I felt an intuitive explanation was in order. I hope it's helpful!

Haskell Programming Assignment, "Couldn't match expected type ‘Int’ with actual type ‘[a0] -> Int’ "and a few more Errors

The assignment I have: A function numOccurences that takes a value and a list, returning the number of times that value appears in the list. I am learning haskell and am getting frustrated, this is my code for this:
numOccurences:: b -> [a] -> Int
numOccurences n [ls]
|([ls] !! n==True) = (numOccurences(n (tail [ls])))+1
|otherwise = 0
The errors I am getting are as follows:
https://imgur.com/a/0lTBn
A few pointers:
First, in your type signature, using different type variables (i.e. b and a) creates the possibility that you could look for occurrences of a value of one type, in a list with another type, which in this case is not what you want. So instead of two type variables, you just want to use one.
Second, whatever the concrete type of your list is, whether it's [Char], [Int], etc., it needs to be equatable (i.e. it needs to derive the Eq typeclass), so it makes sense to use the class constraint (Eq a) => in your type signature.
Third, since we're traversing a list, let's use pattern matching to safely break off the first element of the list for comparison, and let's also add a base case (i.e. what we do with an empty list), since we're using recursion, and we only want the recursive pattern to match as long as there are elements in our list.
Lastly, try to avoid using indexing (i.e. !!), where you can avoid it, and use pattern matching instead, as it's safer and easier to reason about.
Here's how your modified function might look, based on the above pointers:
numOccurences :: (Eq a) => a -> [a] -> Int
numOccurences _ [] = 0
numOccurences n (x:xs)
| n == x = 1 + numOccurences n xs
| otherwise = numOccurences n xs

"For all" statements in Haskell

I'm building comfort going through some Haskell toy problems and I've written the following speck of code
multipOf :: [a] -> (Int, a)
multipOf x = (length x, head x)
gmcompress x = (map multipOf).group $ x
which successfully preforms the following operation
gmcompress [1,1,1,1,2,2,2,3] = [(4,1),(3,2),(1,3)]
Now I want this function to instead of telling me that an element of the set had multiplicity 1, to just leave it alone. So to give the result [(4,1),(3,2),3] instead. It be great if there were a way to say (either during or after turning the list into one of pairs) for all elements of multiplicity 1, leave as just an element; else, pair. My initial, naive, thought was to do the following.
multipOf :: [a] -> (Int, a)
multipOf x = if length x = 1 then head x else (length x, head x)
gmcompress x = (map multipOf).group $ x
BUT this doesn't work. I think because the then and else clauses have different types, and unfortunately you can't piece-wise define the (co)domain of your functions. How might I go about getting past this issue?
BUT this doesn't work. I think because the then and else clauses have different types, and unfortunately you can't piece-wise define the (co)domain of your functions. How might I go about getting past this issue?
Your diagnosis is right; the then and else must have the same type. There's no "getting past this issue," strictly speaking. Whatever solution you adopt has to use same type in both branches of the conditional. One way would be to design a custom data type that encodes the possibilities that you want, and use that instead. Something like this would work:
-- | A 'Run' of #a# is either 'One' #a# or 'Many' of them (with the number
-- as an argument to the 'Many' constructor).
data Run a = One a | Many Int a
But to tell you the truth, I don't think this would really gain you anything. I'd stick to the (Int, a) encoding rather than going to this Run type.

What does [a] stand for exactly?

I'm doing some exercises from "Real World Haskell". One is to design a safe version of init :: [a] -> [a].
I'm supposed to start from safeInit :: [a] -> Maybe [a]
This is what I have at the moment.
safeInit :: [a] -> Maybe [a]
safeInit [] = Nothing
safeInit [a] = if length [a] <= 1
then Nothing
else Just (take (length [a] -1) [a])
In GCHi, when testing safeInit [1,2] I get the error message
* Exception: ch4exercise.hs:(21,1)-(24,44): Non-exhaustive patterns in function safeInit
I was under the impression that [a] simply stands for a list (of any size) of a's. What am I doing wrong?
As a type, [a] does stand for "a list of any size of as". As a pattern however, [a] stands for "a list containing exactly one element, which shall henceforth be known by the name a". Similarly [a,b] would mean "a list containing two elements, the first of which shall be known as a and the second of which shall be known as b" and so. [], as you already seem to know, stands for "a list containing exactly 0 elements".
This is analogous to how you'd write list literals as expressions. I.e. if you write myList = [], myList is the empty list and if you write myList = [x], myList is a list containing exactly one element, which is the value of the variable x.
[] is the empty list, a list containing nothing.
[a] is a list containing exactly one element, and that element (not the list) will be identified as "a" in the function.
You therefore still need to consider the case where the list contains several elements.
If you just use "a" rather than "[a]", then "a" will refer to the whole list, and you can start taking it apart with the functions you have to hand.
Note that you've already dealt with the situation in which you have an empty list, so you shouldn't need to check it again in the if statement.
One thing you'll have to get used to in Haskell, which isn't very intuitive until you're reasonably experienced, is that the "namespace" for type-level things is completely separate from the namespace for value-level things. This means the same source text can have a completely different meaning when you're talking about types than when you're talking about values.
safeInit :: [a] -> Maybe [a]
Everything following the :: is talking about types. Here [a] is the list type constructor applied to the type variable a.1 So it's the type of lists (of any size) whose elements are of type a.
safeInit [a] = if length [a] <= 1
...
OTOH this equation is at the value level. Here [a] isn't a type, it's a value (on the left hand side of the = it's a pattern to be matched by the value to which safeInit was applied; on the right hand side it's just a value). At the value level the square bracket syntax isn't the list type constructor, it's syntactic sugar for writing lists, with all the elements of the lists separated by commas inside the brackets. So [a] is the value of a list containing one single element, which is denoted by the variable a. If we wanted the list to be empty we'd write []. If we wanted the list to contain just a and b we'd write [a, b], etc.
At the value level it wouldn't make much sense for [a] to be a list of any number of as, because (during any particular evaluation of this code) a is one particular value, such as 3.4. What use is an expression for a list of any number of 3.4s?
1 Just as Maybe a is the Maybe type constructor applied to the type variable a; the only thing that's special about the list type constructor is that it's called [] rather than a normal name, and gets this odd "surrounding" syntax for application rather than the usual prefix form.
There's a problem with this line:
safeInit [a] = if length [a] <= 1
On the left side of the equation, [a] will match a list with exactly one element. So the compiler sees that you have a version of safeInit for an empty list, a version of safeInit for a list with one element, but nothing for a list with more elements. That's why it's complaining about Non-exhaustive patterns.
I think that what you really want is
safeInit a = if length a <= 1
then Nothing
else Just (take (length a -1) a)
To summarise:
In a type signature, [a] stands for a list of elements of arbitrary type a.
In a pattern, [a] matches a list with exactly one element.

Resources