A curried version of union for a fold? - haskell

I have this simple version of a set union
union (s, []) = s
union (s, t:ts) | member (t,s) = union (s,ts)
| otherwise = t : union (s,ts)
where member is a version of elem. But this, which I found in a textbook, says the union must be a curried union
uniteElems [] = []
uniteElems (h:t) = union h (uniteElems t)
This has me confused. As the text says, uniteElems is a sort of proto-fold (foldr?), i.e., it should take a single list and recursively apply union, thereby weeding out the duplicates. So is this my "curried version" of a union
union2 s [] = s
union2 s (t:ts) | elem t s = union2 s ts
| otherwise = union2 (t:s) ts
In any event, this union2 doesn't work as-is in uniteElems, giving an error.
* Non type-variable argument in the constraint: Num [a]
: (Use FlexibleContexts to permit this)
: * When checking the inferred type
: it :: forall a. (Eq a, Num [a]) => [a]
This version, however, does work
uniteElems [] = []
uniteElems (h:t) = union2 [h] (uniteElems t)
but I've kludged in the [h]. What would make uniteElems, a sort of proto-fold, work? How would a union function look for regular use with foldr would be another related question, I suppose.

There seems to be some confusion in your code over the desired meaning (purpose, or semantics) of your various functions. Related to that, there is definitely some confusion over the types of the functions.
Let's start with uniteElems. It seems to have type Eq a => [a] -> [a] along with some documented guarantee that the input list is a regular old list while the output list is actually a set. It relies on there existing a function union :: Eq a => a -> [a] -> [a]. Looking at the definition of uniteElems, it seems to be that this union function should take an element and a set (represented as a list) and add the element to the set.
Now, let's look at your definition of union2 (or similar for union, just uncurried). It has type Eq a => [a] -> [a] -> [a], and its meaning seems to be that if it is given two lists that represent sets, it will return a list representing the union of the two sets.
Right away, it seems pretty clear what the problem is: the union expected in uniteElems and the union2 you have defined are fundamentally different! One is adding a single element to a set and the other is combining two whole sets.
Now, it also seems clear why your proposed modification to uniteElems works: basically, you're taking each individual element, turning it into a singleton set, and then using your union2 function to combine those sets.
In order to make uniteElems do what you want, you need a simpler definition of union, like:
union :: Eq a => a -> [a] -> [a]
union t s | elem t s = s
| otherwise = t:s
As for folds and proto-folds, uniteElems is a protofold because it is essentially a fold where some of the arguments have been supplied. That is, you could write:
uniteElems = foldr union []

Related

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

Recursively merge list of lists based on shared elements

I don't know what the official technical name is for what I'm trying to do so I'll try to explain it as best I can.
Given a list of lists:
[[2,3,4,5], [1,5,6], [7,8,9]]
I want to union only the lists that have atleast one common element. So basically something like this:
simUnion :: [[Int]] -> [[Int]]
simUnion list = --...
--Result
-- [[1,2,3,4,5,6], [7,8,9]]
The problem I'm running into is running a match process between each element. Basically this is like the old math class problem where each person in a room must shake the hand of each other person. Ordinarily I'd accomplish this with a nested for loop, but how can I do this using Haskell's recursion?
Any help at all would be great!
If there is a finite number of distinct elements, you can turn the task inside out and make a Ord elem => Map elem [[elem]] out of your [[elem]] and then start iteratively merging the elements by the next algorithm:
while map isn't empty, take away a key, put it in the queue
get all the groups containing key popped from the queue
concat them and put into the queue (and in some accumulator, too)
if the queue got empty, the group is finished; take another key from the map
Note: The following post is written in literate Haskell. Save it as *.lhs and load it in GHCi. Also note that the discussed algorithm has runtime O(n²) and isn't optimal. A better approach would use union find or similar.
First, let us think about the tools we need if we want to group a single list x with the rest of the lists xs. We need to separate between the lists from xs that have an element in common with x, and we need to build the union of such lists. Therefore, we should import some functions from Data.List:
> import Data.List (partition, union)
Next, we need to check whether two lists are suitable to get merged:
> intersects :: Eq a => [a] -> [a] -> Bool
> intersects xs ys = any (`elem` ys) xs
Now we have all the tools at hand to define simUnion. The empty case is clear: if we don't have any lists, the result doesn't have any list either:
> simUnion :: Eq a => [[a]] -> [[a]]
> simUnion [] = []
Suppose we have at least two lists. We take the first one and check whether they have any element in common with any other list. We can do so by using partition:
> simUnion (x:xs) =
> let (common, noncommon) = partition (intersects x) xs
Now, common :: [[a]] will only contain those lists that have at least one element in common. There can be two cases now: either common is empty, and our list x has no element in common with any list from xs:
> in if null common
> then x : simUnion xs
We ignore uncommon here, since xs == uncommon in this case. In the other case, we need to build the union of all lists in common and x. This can be done with foldr union. However, this new list must be used in simUnion again, since it may have new intersections. For example, in
simUnion [[1,2], [2,3], [3,4]]
you want to end up with [[1,2,3,4]], not [[1,2,3],[3,4]]:
> else simUnion (foldr union x common : noncommon)
Note that the result will be unsorted, but you can map sort over it as a last step.
I have two main recommendations:
Don't think of it in terms of recursion! Instead, make liberal use of library utility functions.
Use appropriate data structures! Since you're talking about membership tests and unions, sets (from the Data.Set module) sound like they would be a better choice.
Applying those ideas, here's a fairly simple (though perhaps very naïve and suboptimal) solution:
import Data.Set (Set)
import qualified Data.Set as Set
simUnion :: Set (Set Int) -> Set (Set Int)
simUnion sets = Set.map outer sets
where outer :: Set Int -> Set Int
outer set = unionMap middle set
where middle :: Int -> Set Int
middle i = unionMap inner sets
where inner :: Set Int -> Set Int
inner set
| i `Set.member` set = set
| otherwise = Set.empty
-- | Utility function analogous to the 'concatMap' list function, but
-- for sets.
unionMap :: (Ord a, Ord b) => (a -> Set b) -> Set a -> Set b
unionMap f as = Set.unions (map f (Set.toList as))
Now using your example:
-- | This evaluates to:
--
-- >>> simUnion sampleData
-- fromList [fromList [1,2,3,4,5,6],fromList [7,8,9]]
sampleData :: Set (Set Int)
sampleData = Set.fromList (map Set.fromList sampleData')
where sampleData' :: [[Int]]
sampleData' = [[2,3,4,5], [1,5,6], [7,8,9]]
Ordinarily I'd accomplish this with a nested for loop, but how can I do this using Haskell's recursion?
You don't use recursion directly. You use higher-order functions like Set.map and unionMap. Note that these functions are analogous to loops, and that we're using them in a nested manner. Rule of thumb: imperative for loops very often translate to functional map, filter, reduce or similar operations. Nested imperative loops correspondingly often translate to nested use of such functions.

Searching through tuple of more than 2 elements

How can I search a tuple based on the first element or second or third?
I know how to search tuple of two but how do i do it for more than two?
type Stuff = (String, String, Int)
testStuff :: [Stuff]
testStuff = [
("beans","black",5),
("cod","fish",4),
("coke","diet",3)
]
How can I write a function that will search "Stuff" and return the "int" value?
e.g searchStuff "beans" should return 5.
Since you haven't provided your function for searching in a list of pairs, I'm going to assume that you used lookup. Lets focus on find for your new function. find can be found in Data.List (and a more general version in Data.Foldable) and has the following type:
find :: (a -> Bool) -> [a] -> Maybe a
Now, if you need to find something in a list of triples based on the first element, you could use
find (\(a,_,_) -> a == "beans") testStuff
However, this will leave you with a Maybe Stuff. But since Maybe is an instance of Functor, it is easy to change the result to Maybe Int (and is left as an exercise).
The Prelude defines lookup to handle searching a list of pairs. Here's the definition:
-- | 'lookup' #key assocs# looks up a key in an association list.
lookup :: (Eq a) => a -> [(a,b)] -> Maybe b
lookup _key [] = Nothing
lookup key ((x,y):xys)
| key == x = Just y
| otherwise = lookup key xys
Can you see how one would define a similar function to search a list of triples?

Creating a list type using functions

For a silly challenge I am trying to implement a list type using as little of the prelude as possible and without using any custom types (the data keyword).
I can construct an modify a list using tuples like so:
import Prelude (Int(..), Num(..), Eq(..))
cons x = (x, ())
prepend x xs = (x, xs)
head (x, _) = x
tail (_, x) = x
at xs n = if n == 0 then xs else at (tail xs) (n-1)
I cannot think of how to write an at (!!) function. Is this even possible in a static language?
If it is possible could you try to nudge me in the right direction without telling me the answer.
There is a standard trick known as Church encoding that makes this easy. Here's a generic example to get you started:
data Foo = A Int Bool | B String
fooValue1 = A 3 False
fooValue2 = B "hello!"
Now, a function that wants to use this piece of data must know what to do with each of the constructors. So, assuming it wants to produce some result of type r, it must at the very least have two functions, one of type Int -> Bool -> r (to handle the A constructor), and the other of type String -> r (to handle the B constructor). In fact, we could write the type that way instead:
type Foo r = (Int -> Bool -> r) -> (String -> r) -> r
You should read the type Foo r here as saying "a function that consumes a Foo and produces an r". The type itself "stores" a Foo inside a closure -- so that it will effectively apply one or the other of its arguments to the value it closed over. Using this idea, we can rewrite fooValue1 and fooValue2:
fooValue1 = \consumeA consumeB -> consumeA 3 False
fooValue2 = \consumeA consumeB -> consumeB "hello!"
Now, let's try applying this trick to real lists (though not using Haskell's fancy syntax sugar).
data List a = Nil | Cons a (List a)
Following the same format as before, consuming a list like this involves either giving a value of type r (in case the constructor was Nil) or telling what to do with an a and another List a, so. At first, this seems problematic, since:
type List a r = (r) -> (a -> List a -> r) -> r
isn't really a good type (it's recursive!). But we can instead demand that we first reduce all the recursive arguments to r first... then we can adjust this type to make something more reasonable.
type List a r = (r) -> (a -> r -> r) -> r
(Again, we should read the type List a r as being "a thing that consumes a list of as and produces an r".)
There's one final trick that's necessary. What we would like to do is to enforce the requirement that the r that our List a r returns is actually constructed from the arguments we pass. That's a little abstract, so let's give an example of a bad value that happens to have type List a r, but which we'd like to rule out.
badList = \consumeNil consumeCons -> False
Now, badList has type List a Bool, but it's not really a function that consumes a list and produces a Bool, since in some sense there's no list being consumed. We can rule this out by demanding that the type work for any r, no matter what the user wants r to be:
type List a = forall r. (r) -> (a -> r -> r) -> r
This enforces the idea that the only way to get an r that gets us off the ground is to use the (user-supplied) consumeNil function. Can you see how to make this same refinement for our original Foo type?
If it is possible could you try and nudge me in the right direction without telling me the answer.
It's possible, in more than one way. But your main problem here is that you've not implemented lists. You've implemented fixed-size vectors whose length is encoded in the type.
Compare the types from adding an element to the head of a list vs. your implementation:
(:) :: a -> [a] -> [a]
prepend :: a -> b -> (a, b)
To construct an equivalent of the built-in list type, you'd need a function like prepend with a type resembling a -> b -> b. And if you want your lists to be parameterized by element type in a straightforward way, you need the type to further resemble a -> f a -> f a.
Is this even possible in a static language?
You're also on to something here, in that the encoding you're using works fine in something like Scheme. Languages with "dynamic" systems can be regarded as having a single static type with implicit conversions and metadata attached, which obviously solves the type mismatch problem in a very extreme way!
I cannot think of how to write an at (!!) function.
Recalling that your "lists" actually encode their length in their type, it should be easy to see why it's difficult to write functions that do anything other than increment/decrement the length. You can actually do this, but it requires elaborate encoding and more advanced type system features. A hint in this direction is that you'll need to use type-level numbers as well. You'd probably enjoy doing this as an exercise as well, but it's much more advanced than encoding lists.
Solution A - nested tuples:
Your lists are really nested tuples - for example, they can hold items of different types, and their type reveals their length.
It is possible to write indexing-like function for nested tuples, but it is ugly, and it won't correspond to Prelude's lists. Something like this:
class List a b where ...
instance List () b where ...
instance List a b => List (b,a) b where ...
Solution B - use data
I recommend using data construct. Tuples are internally something like this:
data (,) a b = Pair a b
so you aren't avoiding data. The division between "custom types" and "primitive types" is rather artificial in Haskell, as opposed to C.
Solution C - use newtype:
If you are fine with newtype but not data:
newtype List a = List (Maybe (a, List a))
Solution D - rank-2-types:
Use rank-2-types:
type List a = forall b. b -> (a -> b -> b) -> b
list :: List Int
list = \n c -> c 1 (c 2 n) -- [1,2]
and write functions for them. I think this is closest to your goal. Google for "Church encoding" if you need more hints.
Let's set aside at, and just think about your first four functions for the moment. You haven't given them type signatures, so let's look at those; they'll make things much clearer. The types are
cons :: a -> (a, ())
prepend :: a -> b -> (a, b)
head :: (a, b) -> a
tail :: (a, b) -> b
Hmmm. Compare these to the types of the corresponding Prelude functions1:
return :: a -> [a]
(:) :: a -> [a] -> [a]
head :: [a] -> a
tail :: [a] -> [a]
The big difference is that, in your code, there's nothing that corresponds to the list type, []. What would such a type be? Well, let's compare, function by function.
cons/return: here, (a,()) corresponds to [a]
prepend/(:): here, both b and (a,b) correspond to [a]
head: here, (a,b) corresponds to [a]
tail: here, (a,b) corresponds to [a]
It's clear, then, that what you're trying to say is that a list is a pair. And prepend indicates that you then expect the tail of the list to be another list. So what would that make the list type? You'd want to write type List a = (a,List a) (although this would leave out (), your empty list, but I'll get to that later), but you can't do this—type synonyms can't be recursive. After all, think about what the type of at/!! would be. In the prelude, you have (!!) :: [a] -> Int -> a. Here, you might try at :: (a,b) -> Int -> a, but this won't work; you have no way to convert a b into an a. So you really ought to have at :: (a,(a,b)) -> Int -> a, but of course this won't work either. You'll never be able to work with the structure of the list (neatly), because you'd need an infinite type. Now, you might argue that your type does stop, because () will finish a list. But then you run into a related problem: now, a length-zero list has type (), a length-one list has type (a,()), a length-two list has type (a,(a,())), etc. This is the problem: there is no single "list type" in your implementation, and so at can't have a well-typed first parameter.
You have hit on something, though; consider the definition of lists:
data List a = []
| a : [a]
Here, [] :: [a], and (:) :: a -> [a] -> [a]. In other words, a list is isomorphic to something which is either a singleton value, or a pair of a value and a list:
newtype List' a = List' (Either () (a,List' a))
You were trying to use the same trick without creating a type, but it's this creation of a new type which allows you to get the recursion. And it's exactly your missing recursion which allows lists to have a single type.
1: On a related note, cons should be called something like singleton, and prepend should be cons, but that's not important right now.
You can implement the datatype List a as a pair (f, n) where f :: Nat -> a and n :: Nat, where n is the length of the list:
type List a = (Int -> a, Int)
Implementing the empty list, the list operations cons, head, tail, and null, and a function convert :: List a -> [a] is left as an easy exercise.
(Disclaimer: stole this from Bird's Introduction to Functional Programming in Haskell.)
Of course, you could represent tuples via functions as well. And then True and False and the natural numbers ...

What to call a function that splits lists?

I want to write a function that splits lists into sublists according to what items satisfy a given property p. My question is what to call the function. I'll give examples in Haskell, but the same problem would come up in F# or ML.
split :: (a -> Bool) -> [a] -> [[a]] --- split lists into list of sublists
The sublists, concatenated, are the original list:
concat (split p xss) == xs
Every sublist satisfies the initial_p_only p property, which is to say (A) the sublist begins with an element satisfying p—and is therefore not empty, and (B) no other elements satisfy p:
initial_p_only :: (a -> Bool) -> [a] -> Bool
initial_p_only p [] = False
initial_p_only p (x:xs) = p x && all (not . p) xs
So to be precise about it,
all (initial_p_only p) (split p xss)
If the very first element in the original list does not satisfy p, split fails.
This function needs to be called something other than split. What should I call it??
I believe the function you're describing is breakBefore from the list-grouping package.
Data.List.Grouping: http://hackage.haskell.org/packages/archive/list-grouping/0.1.1/doc/html/Data-List-Grouping.html
ghci> breakBefore even [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6]
[[3,1],[4,1,5,9],[2],[6,5,3,5],[8,9,7,9,3],[2,3],[8],[4],[6],[2],[6]]
I quite like some name based on the term "break" as adamse suggests. There are quite a few possible variants of the function. Here is what I'd expect (based on the naming used in F# libraries).
A function named just breakBefore would take an element before which it should break:
breakBefore :: Eq a => a -> [a] -> [[a]]
A function with the With suffix would take some kind of function that directly specifies when to break. In case of brekaing this is the function a -> Bool that you wanted:
breakBeforeWith :: (a -> Bool) -> [a] -> [[a]]
You could also imagine a function with By suffix would take a key selector and break when the key changes (which is a bit like group by, but you can have multiple groups with the same key):
breakBeforeBy :: Eq k => (a -> k) -> [a] -> [[a]]
I admit that the names are getting a bit long - and maybe the only function that is really useful is the one you wanted. However, F# libraries seem to be using this pattern quite consistently (e.g. there is sort, sortBy taking key selector and sortWith taking comparer function).
Perhaps it is possible to have these three variants for more of the list processing functions (and it's quite good idea to have some consistent naming pattern for these three types).

Resources