in preparation for an exam on haskell our teacher gave us some exercises but was then sick on the day we were supposed to discuss them. Some of them I solved, some of them I can't figure out:
1) Write a function that calculates the parts of vodka and energy in a longdrink:
data VodkaEnergy = Vodka Int | Energy Int | Mix VodkaEnergy VodkaEnergy
I didn't manage to do much more than:
mixPortion :: VodkaEnergy->(Int,Int)
mixPortion (Vodka x) = (x,0)
mixPortion (Energy y) = (0,y)
mixPortion (Mix x y) = (a,b)
where a = fst (mixPortion x)
b = snd (mixPortion y)
I realize this is a oversimplified solution that doesn't catch all inputs but I'm at a loss.
1b) VodkaEnergy should be a part of Eq, making 2 longdrinks equal if they have the same ratio of vodka and energy.
This one I can't solve until I have the function but I'm assuming it would go like this:
instance Eq VodkaEnergy where
x == y = mixPortion x == mixPortion y
typeclasses are still difficult for me, so do correct me.
2) Write a function that counts the paths that has an even amount of Leaves + Nodes in
data Tree = Leaf Int | Ndoe Int Tree Tree
Again, at a loss all I got so far is a function that counts all nodes and leaves in the tree, which doesn't help much
3)
data Eq a => Set a = S [a]
Make set an instance of Eq, where two sets are the same if all elements of set1 are contained in set2 and vice versa.
This one confuses me because the data type in the task doesn't compile with the "Eq a =>" there. But what I tried so far is this:
instance (Eq a) => Eq (Set a) where
x:set1 == set2 = x `elem` set2 && set1 == set2 && set2 == set1
but the "x:set1" part doesn't compile because it expects a different type
I know these are probably newbie questions. I mean, I AM a newbie to haskell. I'm finding it hard to find good ressources for questions on haskell like these, so do link me if I missed the answers floating on the web somewhere. I'm honestly a little desperate, the exam is coming closer and I still don't quite 'get' functional programming. Thank you very much for any help.
a) Almost good, but you have to add up the vodka and energy components of both parts of the mix, not just the vodka from the first and the energy from the second. Furthermore it is often nicer to use pattern-matching instead of accessor methods like
fst
andsnd
if possible.b) is correct.
As I said in the comment I don't really know what exactly question wants. Assuming that the task is to find the number of even paths from the root to any leaf, you could approach it like this: You write a function
evenOddBranches :: Tree -> (Int,Int)
that gives the number of even paths and odd paths. This is easier, since an even path of a subtree of a node is an odd path if you add that node to the path. That way you get a simple recursion: The number even paths of a node are the sum of the odd paths of it's two subtrees and the number odd paths is the sum of the even paths of the subtrees.The
Eq
constraint onSet
used to be correct syntax but isn't anymore since Haskell 2010. The correct way to do this is to just leaf out theEq
constraint in the data definition and add it where needed.There are also some flaws with your code. First of all you can not pattern-match on it with
x:set1
, because it is not a list, but aSet
, which means you have theS
wrapper. So instead you have to pattern-match like this:S (x:xs)
. Note thatxs
is a list and not aSet
, so for the recursive call you have to wrap it withS
again. Furthermore if you match onS (x:xs)
you should also match onS []
. So fixing your code on a syntactical level we get the following:This will compile but does not work. For example with
S [0] == S [0]
isFalse
.The easiest way to write a set equality is with two set inclusions. So you should write a function
subsetEq :: Eq a => Set a -> Set a -> Bool
that isTrue
iff every element of the first set is also an element of the second set. Then you can implement set equality like this:I think with only an
Eq
constraint this is actually the best you can do.