Haskell error using foldr - haskell

I am new to haskell and trying out some exercises
I dont understand whats the error generated and why it is generated
split = foldr
(\x y -> y:x)
[[]]
the error on the interpretator is as below
Occurs check: cannot construct the infinite type: a0 = [a0]
In the first argument of `(:)', namely `y'
In the expression: y : x
In the first argument of `foldr', namely `(\ x y -> y : x)'
Failed, modules loaded: none.
anyone can help? Thanks in advance

Type of foldr is
foldr :: (a -> b -> b) -> b -> [a] -> b
so in split
split = foldr (\x y -> y:x) [[]]
y and y:x has to be of same type, which is not possible for any x and y as y:x will always be one step deeper in the list than y.
I think you wanted to do x:y?

Recall the type of foldr: (a -> b -> b) -> b -> [a] -> b. This says that foldr expects a function that combines an element of the list with a value of the final result type, producing a new value of the result type.
For the first argument, you've given foldr the function \x y -> y:x, where x will be the list elements and y the result of the next step to the right; and the result of applying this lambda should have the same type as y.
But the type of (:) is a -> [a] -> [a]--that is, it appends a single element to the head of a list. In the expression y:x, you're taking something of the "result" type and using it as an element of a list used as the result.
Because of that, GHC attempts to infer that the result type b is the same as the type [b], which is then of course the same as the type [[b]], and [[[b]]]... and so on. Thus it complains about an "infinite type".

The posts before me answer your question, but after your comment i can see that you want a function that splits your list by a predicate.
You can use groupWith::Ord b => (a -> b) -> [a] -> [[a]] from the module GHC.Exts and supply it with a function of type (a -> Bool) in your example:
groupWith even [1,2,3,4,5,6] yields [[1,3,5],[2,4,6]]
Also, something ugly but that achieves the type of "outing" you want is:
split::Eq a => (a -> Bool) -> [a] -> [[a]]
split f ls = (ls \\ rl):rl:[]
where rl = filter f ls
But this will always split the supplied list in just two lists because of the binary function you supply.

Related

Where clause in haskell function without parameters

substitute':: (Eq a)=> a -> a -> [a] -> [a]
substitute' x y = map substituteOne
where
substituteOne x' | x == x' = y
| otherwise = x'
So, the point of this function is, that it takes two inputs of type a and a list of type a and substitutes all elements in list [a] that are from the "first" a with the "second" a. At least that is what the task description says.
I already implemented a recursive version, but a function with a where clause is also needed.
So THAT is the solution for it. Somehow I have questions:
how can substituteOne in the second line work without any parameters?
where do we give a list as input? or where do we state WHAT we do with that list? I mean compiling and eecuting it works, but somehow I don't see it
what is x' ? it is never defined anywhere, we just start working with it somehow (maybe refers also to question 1)
map needs a function and a list, so that it works. here we have map function _. refers maybe to 2., but what would be the output of substituteOne x' ?
If needed, result looks like this:
substitute' 5 10 [1, 5, 2, 5, 3, 5]
[1,10,2,10,3,10]
(1) how can substituteOne in the second line work without any parameters?
(2) where do we give a list as input? or where do we state what we do with that list? I mean compiling and executing it works, but somehow I don’t see it
The parameters are still there; this is currying at work. Consider the section of an infix operator (+1), which is a special case of partial application. Given a number, it produces a number that is one greater. Witness:
λ> :t (+1)
(+1) :: Num a => a -> a
We could define a function to increment all elements of a list by naming the list
λ> :t \l -> map (+1) l
\l -> map (+1) l :: Num b => [b] -> [b]
but that turns out to be unnecessary because of currying.
λ> :t map (+1)
map (+1) :: Num b => [b] -> [b]
This is functional programming, after all. With Haskell, we manipulate functions as easily as other languages manipulate strings.
(3) what is x'? it is never defined anywhere, we just start working with it somehow (maybe refers also to question 1)
But you do define x' as a parameter of substituteOne!
Consider the type of map:
λ> :t map
map :: (a -> b) -> [a] -> [b]
Its first argument is a function of one parameter. For your program to typecheck, the types have to line up. We can emphasize this for substituteOne by adding an optional type annotation — but have to work a bit harder (by enabling the scoped type variables extension) because substituteOne is an inner function with references to the outer scope,
substitute':: forall a. Eq a => a -> a -> [a] -> [a]
substitute' x y = map substituteOne
where
substituteOne :: a -> a
substituteOne x' | x == x' = y
| otherwise = x'
(4) map needs a function and a list, so that it works. here we have map function _. refers maybe to 2., but what would be the output of substituteOne x'?
Using unnamed arguments at the point of application as your code does with map substituteOne is known as pointfree style. In your case, there are two invisible “points” or variable names: the argument to substituteOne and the list argument to map.
You could be explicit about everything, as in
substitute'' :: Eq a => a -> a -> [a] -> [a]
substitute'' x y l = map (\x' -> if x == x' then y else x') l
but that is much more cluttered in comparison.
The values produced by substituteOne are collected in the list that results from map.
substitute has type a -> a -> [a] -> [a], which means it takes one argument and returns a function of type a -> [a] -> [a]. This is because (->) is right-associative, and the above type is equivalent to a -> (a -> [a] -> [a]).
Since function application is left-associative, a call like substitute x y is equivalent to (substitute x) y; y is the argument to the function returned by substitute x.
When one writes
substitute x y = ...
that is syntactic sugar for
substitute = \x -> \y -> ...
Further, since map substituteOne' has type [a] -> [a], that makes it a suitable value for substitute x y to return.
substitute1 takes a parameter x'. The bits between the | and = characters are guard conditions. Since this particular function has only one condition you could rewrite it like this:
substitute1 x' = if x == x' then y else x'
Because it is in the where clause substitute1 also has access to the parameters x and y of the main function.

Using Haskell's foldr

I'm learning Haskell and I've been wrestling with this problem:
Write func :: (a -> Bool) -> [a] -> [a] (take elements of a list until the predicate is false) using foldr
This is what I have so far:
func :: (a -> Bool) -> [a] -> [a]
func f li = foldr f True li
and got the following errors:
Couldn't match expected type ‘[a]’ with actual type ‘Bool’
and
Couldn't match type ‘Bool’ with ‘Bool -> Bool’
Expected type: a -> Bool -> Bool
Actual type: a -> Bool
I'm a bit confused since I learned foldr by passing a function with two arguments and getting a single value. For example I've used the function by calling
foldr (\x -> \y -> x*y*5) 1 [1,2,3,4,5]
to get a single value but not sure how it works when passing a single argument function into foldr and getting a list in return. Thank you very much.
Let’s do an easier case first, and write a function that uses foldr to do nothing (to break down the list and make a the same list). Let’s look at the type signature of foldr:
foldr :: (a -> b -> b) -> b -> [a] -> [b]
And we want to write an expression of the form
foldr ?1 ?2 :: [a] -> [a]
Now this tells us that (in the signature of foldr) we can replace b with [a].
A thing we haven’t worked out, ?2, is what we replace the end of the list with and it has type b = [a]. We don’t really have anything of type a so let’s just try the most stupid thing we can:
foldr ?1 []
And now the next missing thing: we have ?1 :: a -> [a] -> [a]. Let’s write a function for this. Now there are two reasonable things we can do with a list of things and another thing and nothing else:
Add it to the start
Add it to the end
I think 1 is more reasonable so let’s try that:
myFunc = foldr (\x xs -> x : xs) []
And now we can try it out:
> myFunc [1,2,3,4]
[1,2,3,4]
So what is the intuition for foldr here? Well one way to think of it is that the function passed gets put into your list instead of :, with the other item replacing [] so we get
foldr f x [1,2,3,4]
——>
foldr f x (1:(2:(3:(4:[]))))
——>
f 1 (f 2 (f 3 (f 4 x)))
So how can we do what we want (essentially implement takeWhile with foldr) by choosing our function carefully? Well there are two cases:
The predicate is true on the item being considered
The predicate is false for the item being considered
In case 1 we need to include our item in the list, and so we can try doing things like we did with our identity function above.
In case 2, we want to not include the item, and not include anything after it, so we can just return [].
Suppose our function does the right thing for the predicate "less than 3", here is how we might evaluate it:
f 1 (f 2 (f 3 (f 4 x)))
--T T F F (Result of predicate)
-- what f should become:
1 : (2 : ([] ))
——>
[1,2]
So all we need to do is implement f. Suppose the predicate is called p. Then:
f x xs = if p x then x : xs else []
And now we can write
func p = foldr f [] where
f x xs = if p x then x : xs else []

Cannot scan list of numbers into list of tuples

I'm trying to scan a list of lists and return a list of 2-tuples, the first item the sublist, and the second the sum of the sublist. Here is the function:
listToTups :: (Num a) => [[a]] -> [([a], a)]
listToTups x = scanl (\acc item -> (item, sum item) : acc) [] x
When I try to compile I get this error:
Couldn't match expected type `([a], a)' with actual type `[a0]'
In the second argument of `scanl', namely `[]'
In the expression:
scanl (\ acc item -> (item, sum item) : acc) [] x
This doesn't make sense since the lambda function is clearly returning a list of tuples. What am I doing wrong?
UPDATE
This is what I'm trying to do. Given a list of [Int], I want to return a list of 2-tuples, the first element being the sublist itself, and the second being the sum. So something like:
[[1,2,3], [4,5,6]] -> [([1,2,3], 6), ([4,5,6], 15)]
How can I do this?
Since
scanl :: (b -> a -> b) -> b -> [a] -> [b]
and you demand that
scanl _ _ :: Num c => [[c]] -> [([c], c)]
we conclude that b must be ([c], c) (by unifying the return type of scanl and the return type of the supplied type signature). However, you also demand that
scanl _ []
be well-typed, from which we conclude that b must be [d] (by unifying the type of the second argument to scanl and the type of []). These two constraints -- that b be a tuple type and that b be a list type -- are not compatible.
Your description of what you're trying to achieve isn't so clear to me, and it's not immediately obvious from the code, either, so I can't offer much advice on how to fix it. I can only hope that the above description of the problem is clear enough that it helps you see a solution for yourself.

Haskell- write map function using foldr

I am trying to write the map function using foldr. The problem is that when I ran this code :
> myMap f xs = foldr (\ acc x -> acc :(f x)) [] xs
I have the following problem:
No instance for (Num [a0]) arising from a use of 'it'
but when I run
myMap f xs = foldr (\x acc-> (f x):acc) [] xs
It works perfectly. Any ideas why?
the type of foldr is
foldr :: (a -> b -> b) -> b -> [a] -> b
therefore the binary operation that foldr uses to traverse and accumulate the list
has type (a -> b -> b),it first take an element of the list (type a)then the accumulator (type b) resulting in an expression of type b.
So, your first myMap function does not work becuase you are using "acc" and "x" in reverse order.
You want to apply f to x then append it to the acummulator of type b ( a list in this case)
The error you posted is not coming from your definition of myMap, it's coming from how you're using it. The type of the first myMap is ([a] -> [a]) -> [a] -> [a], which does not match the type of Prelude.map. In the second one you've swapped your variable names and also which one you're applying f to. The compiler doesn't care what you name the arguments in your lambda being passed to foldr, so foldr (\x acc -> f x : acc) is identical to foldr (\foo bar -> f foo : bar). That may be what's tripping you up here.
The second one works because (to put it simply) it's correct. In the first you're applying f to your accumulator list x (even though you have a variable named acc it's not your accumulator), so f must take a list and return a list. In the second you're applying f to each element, then prepending that to your accumulator list. If you had myMap (+1), it would have the type
myMap (+1) :: Num [a] => [a] -> [a]
Which says that you must pass it a list of values [a] where [a] implements Num, and currently there is no instance for Num [a], nor will there ever be.
TL;DR: In the first one you're applying your mapped function to your accumulator list, in the second one you're applying the mapped function to each element.

Does haskell's foldr always take a two-parameter lambda?

Haskell newb here
I'm working on this problem in haskell:
(**) Eliminate consecutive duplicates of list elements.
If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.
Example:
* (compress '(a a a a b c c a a d e e e e))
(A B C A D E)
The solution (which I had to look up) uses foldr:
compress' :: (Eq a) => [a] -> [a]
compress' xs = foldr (\x acc -> if x == (head acc) then acc else x:acc) [last xs] xs
This foldr, according to the solution, takes two parameters, x and acc. It would seem like all foldr's take these parameters; is there any exception to this? Like a foldr that takes 3 or more? If not, is this convention redundant and can the formula be written with less code?
foldr takes a function of 2 arguments, but this doesn't prevent it from taking a function of 3 arguments provided that function has the right type signature.
If we had a function
g :: x -> y -> z -> w
With
foldr :: (a -> b -> b) -> b -> [a] -> b
Where we want to pass g to foldr, then (a -> b -> b) ~ (x -> y -> z -> w) (where ~ is type equality). Since -> is right associative, this means we can write g's signature as
x -> y -> (z -> w)
and its meaning is the same. Now we've produced a function of two parameters that returns a function of one parameter. In order to unify this with the type a -> b -> b, we just need to line up the arguments:
a -> | x ->
b -> | y ->
b | (z -> w)
This means that b ~ z -> w, so y ~ b ~ z -> w and a ~ x so g's type really has to be
g :: x -> (z -> w) -> (z -> w)
implying
foldr g :: (z -> w) -> [x] -> (z -> w)
This is certainly not impossible, although more unlikely. Our accumulator is a function instead, and to me this begs to be demonstrated with DiffLists:
type DiffList a = [a] -> [a]
append :: a -> DiffList a -> DiffList a
append x dl = \xs -> dl xs ++ [x]
reverse' :: [a] -> [a]
reverse' xs = foldr append (const []) xs $ []
Note that foldr append (const []) xs returns a function which we apply to [] to reverse a list. In this case we've given an alias to functions of the type [a] -> [a] called DiffList, but it's really no different than having written
append :: a -> ([a] -> [a]) -> [a] -> [a]
which is a function of 3 arguments.
As with all things in haskell have a look at the types of things to guide your way you can do this for any function in ghci.
Looking at this for foldr we see:
Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
This slightly abstract string can be written in english as:
foldr is a function that takes
1 ) a function with two parameters one of type a and one of type b and returns something of type b
2 ) A value of type b
3 ) A list of values of type a
And returns a value of type b
Where a and b are type variables (see here for a good tutorial on them) which can be filled in with any type you like.
It turns out that you can solve your compress problem using a foldr with a three-argument function.
compress :: Eq a => [a] -> [a]
compress [] = []
compress (z:zs) = z : foldr f (const []) zs z
where f x k w | x==w = k x
| otherwise = x : k x
Let's dissect that. First, we can improve readability by changing the last two lines to
where f x k = \w -> if x==w then k x else x : k x
This makes it evident that a ternary function is nothing but a binary function returning a unary function. The advantage of looking at it in this way is that foldr is best understood when passed a binary function. Indeed, we are passing a binary function, which just happens to return a function.
Let's focus on types now:
f :: a -> (a -> [a]) -> (a -> [a])
f x k
So, x::a is the element of the list we are folding on. Function k is the result of the fold on the list tail. The result of f x k is something having the same type as k.
\w -> if .... :: (a -> [a])
The overall idea behind this anonymous function is as follows. The parameter k plays the same role as acc in the OP code, except it is a function expecting the previous element w in the list before producing the accumulated compressed list.
Concretely, we use now k x when we used acc, passing on the current element to the next step, since by that time x will become the previous element w. At the top-level, we pass z to the function which is returned by foldr f (const []).
This compress variant is lazy, unlike the posted solution. In fact, the posted solution needs to scan the whole list before starting producing something: this is due to (\x acc -> ...) being strict in acc, and to the use of last xs. Instead, the above compress outputs list elements in a "streaming" fashion. Indeed, it works with infinite lists as well:
> take 10 $ compress [1..]
[1,2,3,4,5,6,7,8,9,10]
That being said, I think using a foldr here feels a bit weird: the code above is arguably less readable than the explicit recursion.

Resources