Why cant I do [1] :: [1] but [1] :: [1] :: [] - ocaml

Why can't I use [1] :: [1] but [1] :: [1] :: []?
I tried to do [1] :: [1]. Got this error:
Error: This expression has type int but an expression was expected of type int list
When I do [1] :: [1] :: [] I get this: - : int list list = [[1]; [1]]

[] is the empty list
x :: [] is the same as [x]
x :: [y] is the same as x :: y :: [] and as [x; y]
With your particular examples:
[1] :: [] is the same as [[1]]
[1] :: [1] :: [] is the same as [[1]; [1]]
[1] :: [1] would be the same as [1] :: 1 :: [] and [[1]; 1], but you can't have a list containing mixed types.

#Stef's answer is good. Here is another similar answer.
First, :: is a right associative operator with two operands. The left operand can have any type and the right operand must be a list of that type. The result of the operator is a list with the same type as the right operand.
Second [] is an empty list that can have any element type.
Written out fully, lists look like this: a :: b :: c :: ... :: []. But they can be written more conveniently as [a ; b ; c ; ... ]. The empty list (as mentioned) is []. A list of one element looks like this: [x].
Finally, the elements of a list must all be the same type.
So here is your first case:
[1] :: [1] :: []
This is a valid list because the elements are all the same type (necessarily since they're the same) and the :: operators are used correctly with a type on the left and a list of that type on the right. Note that this is only the case because :: is right associative. So the rightmost :: is applied first. You could also write this list as [ [1] ; [1] ].
Here is your second case:
[1] :: [1]
The operator :: here is not applied correctly. The requirement is that the type of the value on the right be a list of the type of the value on the left. Another way to say this is that int list is not a list whose elements are type int list. To make this valid you can change the left value to be 1 (then you have int and int list as operands of ::) or the right value to be [[1]] (then you have int list and int list list as operands of ::).

Related

Haskell Error - No instance for (Num a) arising from the literal ‘1’

I am trying to create a function which adds a 1 before each of the entries in a given list. I haven't quite grasped the syntax for Haskell and am wondering what is wrong with this code. For example, I would like this to return the list [1,1,1,2,1,3]
ins1 :: [a] -> [a]
ins1 [x] = [x]
ins1 (x:xs) = [1] ++ [x] ++ ins1(xs)
main = print(ins1 [1,2,3])
I get the error:
• No instance for (Num a) arising from the literal ‘1’
Possible fix:
add (Num a) to the context of
the type signature for:
ins1 :: [a] -> [a]
• In the expression: 1
In the first argument of ‘(++)’, namely ‘[1]’
In the expression: [1] ++ [x] ++ ins1 (xs)
<interactive>:3:1: error:
• Variable not in scope: main
• Perhaps you meant ‘min’ (imported from Prelude)
Well like the error says, you use ins1, and you write [1] ++ [x] ++ ....
Now 1 is a numerical literal, so it can take all numerical types. Hence 1 has type Num b => b, as a result [1] has type Num b => [b].
Later you append the list with x and recursion, hence we now know that a ~ b (a and b are the same type). So we have to add a type constraint to the signature for a:
ins1 :: Num a => [a] -> [a]
ins1 [x] = [x]
ins1 (x:xs) = [1] ++ [x] ++ ins1(xs)
This solves the compile error, but probably will not generate what you want. Since now there is no case for the empty list. Indeed, both the [x] pattern and the (x:xs) pattern work with lists that respectively match with lists with exactly one element, and at least one element.
Therefore I think that your first clause should actually match the empty list:
ins1 :: Num a => [a] -> [a]
ins1 [] = []
ins1 (x:xs) = [1] ++ [x] ++ ins1(xs)
There is also an inefficiency in the second clause: you append to a list of one element, so we can use the "cons" data cosntructor (:) here:
ins1 :: Num a => [a] -> [a]
ins1 [] = []
ins1 (x:xs) = 1 : x : ins1 xs
This will insert a 1 for every element in the original list, so:
Prelude> ins1 [1, 4, 2, 5]
[1,1,1,4,1,2,1,5]
If you give me a function of type [a] -> [a], you’re saying that, for all types a that I choose, if I give you a list of values of type a, then you can give me back a list of elements of that type.
So if I choose a to be Int by giving you [2, 3, 4] :: [Int], then all is well: the literal 1 in the implementation of ins1 is constrained from Num t => t by t = Int to Num Int => Int. That works because there is an instance Num Int.
However, if I choose a to be Char, by giving you ['a', 'b', 'c'] (= "abc"), then t = Char, giving Num Char => Char, which is an error because there’s no instance Num Char. Therefore, this is a counterexample for the type: your function doesn’t work for all a, only those a that have an instance of Num. So you need to express this constraint in the type signature:
ins1 :: (Num a) => [a] -> [a]
The compiler can infer this for you, and will display a warning about a missing type signature if -Wall is enabled (or -Wmissing-signatures specifically). This will also warn about the fact that ins1 is non-exhaustive: you don’t handle the case of an empty input list. Alternatively, you can enter the definition into GHCi and ask for its type with :type ins1 or :t ins1.
Generic functions in Haskell are parametrically polymorphic, which means that if you have an unconstrained type variable like a, you know nothing about it, not even that it can be constructed from a number literal. So the only things a function of type [a] -> [a] can do are copy, rearrange, or drop elements from the input, or fail to terminate (loop infinitely or raise an error)—it can’t construct new elements or perform any class-specific operations on those elements, such as + from Num or < from Ord.
This may sound limiting, but in fact it’s incredibly useful: the less you know about a type, the fewer options you have for misusing it. And by a neat trick called the Curry–Howard correspondence, you can examine a polymorphic function type like head :: [a] -> a and think of it as a logical formula: does having a list of a imply you can get an a? No, because the list may be empty. So you know that a head function with this type must raise an error if the input is empty, because it has no generic way to construct an a.

"Non-exhaustive patterns" error when summing a list of lists

All I'm trying to do is sum a list of lists. Example of what I want to do:
Input: [[1,2,3],[2,5],[6,7]]
Output: [6,7,13]
The amount of lists inside the outer list can vary, and the amount of integers in each inner list can vary. I've tried a multitude of things, and this is the last one I tried but it doesn't work:
sumSubsets [[x]] = map sum [[x]]
Also, I wanted a base case of sumSubsets [] = [[]] but that causes errors as well. Any help would be appreciated.
You could use
sumSubsets x = map sum x
or even
sumSubsets = map sum
Your previous code,
sumSubsets [[x]] = map sum [[x]]
First performs a pattern match using [[x]] which matches a list containing a single element, which is itself a list containing a single element. Therefore it would work correctly on [[3]]
>> sumSubsets [[3]]
[3]
but not on [[1,2,3]] or [[1],[2]].
I think your problem stems primarily from mixing up types and values, which can happen easily to the beginner, in particular on lists. The whole confusion probably comes from the fact that in Haskell, [] is used as a data constructor as well as a type constructor.
For example, [Int] means "a list of Ints" (a type), but [1] means "the list that contains one element, namely the number 1" (a value -- meaning, the whole list is the value). Both things together:
xs :: [Int]
xs = [1]
When you write polymorphic functions, you abstract from something like the Int. For example, if you want to get the first element of a list, you can define a function that does that for any kind of list -- may they be lists of integers or lists of characters or even lists of lists:
firstElement :: [a] -> a
firstElement (x:xs) = x
[a] means "a list with elements of type a" (a type), and the a alone means "something of type a". firstElement is a function from a list with elements of type a to something of type a. a is a type variable. Since you're not saying what a should be, the function works for all kinds of lists:
*Main> firstElement [1,2,3]
1
*Main> firstElement ['a','b']
'a'
*Main> firstElement [[1,2],[3,4]]
[1,2]
When you wrote [[x]] you were perhaps thinking of the type of the first argument of the function, which would be a list of lists of elements of some type x (x is a type variable). You can still use that, but you have to put it into the type signature of your function (the line that contains the double colon):
sumSubsets :: Num a => [[a]] -> [a]
sumSubsets xs = map sum xs
I've used a here instead of x, since it's more commonly done, but you could use x, too. Unfortunately, the whole thing gets a bit complicated with the Num a which describes additional requirements on the type a (that it belongs to the numbers, since for other things, sum is not defined). To simplify matters, you could write:
sumSubsetsInts :: [[Int]] -> [Int]
sumSubsetsInts xs = map sum xs

What does :: (double colon) mean in Ocaml?

formal_list: typ ID { [($1,$2)] }
| formal_list COMMA typ ID { ($3,$4) :: $1 }
What does the :: operator mean?
For instance: a :: b
Is the meaning that we add a to b?
The :: operator constructs a list. At the left is a list element (the head), at the right is a list (the tail). The operator is right associative, so you can write: 3 :: 4 :: []. The empty list is denoted by [].

Haskell finding the correct number in list

So I want to put in two parameters into this function, a list and the position of the item that I want to print.
listNumber [1,2,3,4,5,6] 2
>> 3
I have tried this problem by doing this
numberList :: (List a) => a -> a -> a
numberList a b = [x | x <- a !! n, n <- b]
I don't know where my mistake is.
I think this is an interesting way of going about it.
If we ignore the type signature for the moment and look at the function:
numberList a b = [x | x <- a !! n, n <- b]
we see that n is called in the first condition of the list-comprehension:
x <- a !! n
but n is only defined after that, in the second condition:
n <- b
This leads to an error: Not in scope: `n'
So the first thing to do might be to switch the first and second conditions:
numberList a b = [x | n <- b, x <- a !! n]
Now asking GHCi about the type, we get:
Prelude> :t numberList
numberList :: [[t]] -> [Int] -> [t]
GHC expects parameter a to be a list of lists and parameter b to be a list of ints. This is because n is drawn from b and anything on the right side of <- in a list comprehension must be a list. Since n is used as a parameter for !!, GHC assumes that n is an int and b is a list of ints.
Now GHC assumes that x is also coming from some kind of list. So we know that GHC assumes a !! n is a list. But since by definition, a !! n is the element of list a at position n, we see why GHC assumes a is a list of lists -- because GHC assumes the element of list a at position n is the list from which x is drawn.
Here's a working example:
Prelude> numberList [[1,2,3,4,5,6]] [0]
[1,2,3,4,5,6]
Here GHC indeed shows us the element of list a at position 0, which is the list [1..6]. Unfortunately, this does not allow us to conveniently get at the positions inside the list, as we would like. An alternate way to still use a list comprehension may be to define a new list 'c' that contains the element we are after (a !! n) and draw x from this new list, like so:
Prelude> let numberList a b = [x | n <- b, let c = [a !! n], x <- c]
Prelude> numberList [1,2,3,4,5,6,3] [2]
[3]
It seems a bit convoluted, though, since we can simply use !! to get the element of a at position b directly:
Prelude> let numberList a b = a !! b
Prelude> numberList [1,2,3,4,5,6] 2
3
So I want to put in two parameters into this function, a list and the position of the item that I want to print.
>>> listNumber [1,2,3,4,5,6] 2
3
Okay. Step one: you have a really messed up type signature.
numberList :: (List a) => a -> a -> a
This should not be ignored. Starting with a good type signature is an essential skill for mastering good programming technique in Haskell and similar languages.
First, you want a function with two inputs.
numberList :: a -> b -> c
Next, you want the first input to be "a list." We don't know what this list contains, so we'll just use a type parameter a. The way to write "a list of a" is [a].
numberList :: [a] -> b -> c
You want the second input to be "the position." This will probably be an Int.
numberList :: [a] -> Int -> c
Finally, you want the result to be an element of the list. So it will therefore have the same type a.
numberList :: [a] -> Int -> a
I have no idea where you got that (List a) => part of the type signature, but it's totally bogus, unless you are using some custom library that you're not telling us about. This is quite possible if you are taking a university course on Haskell.
We have a type signature, and it might be handy to know if this has already been implemented for us. Stop! Hoogle time. Enter the type signature [a] -> Int -> a into http://haskell.org/hoogle . It turns out that you are trying to implement !!.

How do I fix an "Occurs check: cannot construct the infinite type" error?

I am trying to write a remove function, so that a user can type remove 'd' ["abc", "dc", "ad"] and get the output ["abc", "c", "a"].
My code is:
remove :: Eq a => a -> [[a]] -> [[a]]
remove a (x:xs) = filter (not.a) (x:xs)
But I get the following error message:
Occurs check: cannot construct the infinite type: a = [a] -> Bool
When generalising the type(s) for `remove'
What does the error message mean, and how can I change the second line so it works?
The type of filter is
filter :: (a -> Bool) -> [a] -> [a]
so the first argument you pass to filter must be a function from the element-type of the list to Bool. In
remove :: Eq a => a -> [[a]] -> [[a]]
remove a (x:xs) = filter (not.a) (x:xs)
you say
a has type a, and the list has type [[a]], i.e. the list-element type is [a], and
not . a, the first argument to filter, has type [a] -> Bool.
Together, these imply
a = [a] -> Bool
but that is an infinite type.
You probably meant something like filter (not . (a `elem`)), or equivalently filter (a `notElem`), if the filter is meant to work on the outer list, or map (filter (/= a)) if you want to remove an element from each of the contained lists.
You state that the argument a is any type that supports equality.
But you then use it in a boolean expression: not . a.
The type of not is :: Bool -> Bool, so a must be of type Bool. But you already said that no, it was of type Eq t => t.
So that's a type error.
I think you mean to filter all elements that do not equal a, which would be:
remove a xs = filter (/= a) xs
However, your input is also a nested list, so you have to map the filter over the inner elements:
remove a xs = map (filter (/= a)) xs