It was very difficult for me.
One of the problems with your approach is that you are not using the battery correctly, in fact you are passing a union of units, the battery should only store results that match the given predicate p , since you can use the battery in a for or while , it must be initialized with the start value (for example, for Int 0 , for String an empty string, etc.).
As an example, suppose you have List[Int] and you want to count the number of positive numbers:
val list = List(0, -1, -2, 4, 9, -7) def countPositive(list: List[Int]): Int = { def loop(list: List[Int], acc: Int): Int = list match { case Nil => acc case head :: tail => { if( head > 0) loop(tail, acc + 1) else loop(tail, acc) } } loop(list, 0) }
The initial value for this battery is 0 , for example, the same approach should be used for the battery in the filterAcc function.
What you are trying to do is combine the sets and then use them as a standard collection in which you can iterate, I think the problem is to handle a fully functional data structure like this, there there is no collection of sets, but a bunch of objects that are somehow connected. If you remember the video in lecture 3.1 around 7.20, then where Odersky shows that the contains and include operations do not change the three structures, but create a new one, I understand that this is the spirit of the problem.
Returning to the code, you can think of it as a collection that you can repeat to, my approach was to use custom tail and head functions, if tail exists, you can continue iterating to the next object and adding head elements that satisfy the predicate for battery. Each time you repeat, you create a new three structures, avoiding the part that you have already checked, you know if NonEmpty like a left or tight triple using the isEmpty method.
Please note that these methods ( tail and head ) can (in my implementation) be recursive, the very difficult part is that tail always returns new threes objects (as shown in the video when Odersky defines a purely functional structure).
Another suggestion I can give is to try using a bottom-up strategy that always goes back to the last item on the left (or right) with left.isEmpty (or right.isEmpty ) to check where the three ends are, check if add an item to the drive using head , and then create a new three without the item that has just been tested using tail .
It was very difficult for me, and I donβt know if I explained myself correctly, or if this is enough for you to start, unfortunately, for someone like me with very little experience working with purely functional data structures, it is very difficult to explain this without showing the code, good luck.