
I have been working through the exercises in Thompson's The Craft of Functional Programming 2nd Ed book. I am looking for a solution web site for Thompson's book. Or maybe the people here can help. In exercise 4.4, I am asked to define a function howManyOfFourEqual :: Int -> Int -> Int -> Int -> Int which returns the number of integers that are equal to each other. For example, howManyOfFourEqual 1 1 1 1 = 4 howManyOfFourEqual 1 2 3 1 = 2 howManyOfFourEqual 1 2 3 4 = 0 This is my solution. I give it here, since it's not an elegant solution. howManyOfFourEqual :: Int -> Int -> Int -> Int -> Int howManyOfFourEqual a b c d | a == b && howManyEqual b c d /= 0 = howManyEqual b c d + 1 | a == c && howManyEqual b c d /= 0 = howManyEqual b c d + 1 | a == d && howManyEqual b c d /= 0 = howManyEqual b c d + 1 | a == b && howManyEqual b c d == 0 = 2 | a == c && howManyEqual b c d == 0 = 2 | a == d && howManyEqual b c d == 0 = 2 | otherwise = howManyEqual b c d howManyEqual is a function from a previous exercise. howManyEqual :: Int -> Int -> Int -> Int howManyEqual a b c | a == b && b == c = 3 | a /= b && b /= c && a /= c = 0 | otherwise = 2 I hope to find a better solution. I googled but couldn't find the answer. Kaoru Hosokawa khosokawa@gmail.com

Hi Kaoru,
I have been working through the exercises in Thompson's The Craft of Functional Programming 2nd Ed book. I am looking for a solution web site for Thompson's book. Or maybe the people here can help.
In exercise 4.4, I am asked to define a function
howManyOfFourEqual :: Int -> Int -> Int -> Int -> Int
which returns the number of integers that are equal to each other. For example,
howManyOfFourEqual 1 1 1 1 = 4 howManyOfFourEqual 1 2 3 1 = 2 howManyOfFourEqual 1 2 3 4 = 0
A solution which is applicable to any number of arguments is this: import Data.List howManyOfFourEqual a b c d = determineMaxEquals [a,b,c,d] determineMaxEquals :: [a] -> Int determineMaxEquals ls = head $ reverse $ sort $ map length $ group $ sort ls Of course, determineMaxEquals is fubar if used on an infinite list. Regards, Andy

Andy Georges wrote:
Hi Kaoru,
I have been working through the exercises in Thompson's The Craft of Functional Programming 2nd Ed book. I am looking for a solution web site for Thompson's book. Or maybe the people here can help.
In exercise 4.4, I am asked to define a function
howManyOfFourEqual :: Int -> Int -> Int -> Int -> Int
which returns the number of integers that are equal to each other. For example,
howManyOfFourEqual 1 1 1 1 = 4 howManyOfFourEqual 1 2 3 1 = 2 howManyOfFourEqual 1 2 3 4 = 0
A solution which is applicable to any number of arguments is this:
when this example occurs in the text the new Haskell coder has not been introduced to most of what you suggest. Some of the exercises I felt were meant to be a little painful so that when you were introduced to a new concept a chapter or two later you would think "oh, that would have made X.Y so much easier".

Kaoru Hosokawa (khosokawa@gmail.com) wrote:
I hope to find a better solution. I googled but couldn't find the answer.
Here is what I have. I do not have working Haskell interpreter at the moment (being on amd64), but this is what I have in my archive: weakAscendingOrder :: Int -> Int -> Int -> Bool weakAscendingOrder a b c | (a < b) && (b == c) || (a == b) && (b < c) = True | otherwise = False howManyEqual :: Int -> Int -> Int -> Int howManyEqual a b c | (a == b ) && (b == c) = 3 | weakAscendingOrder a b c = 2 | (a /= b) && (b /= c) = 0 isEqual :: Int -> Int -> Int -> Int -> Bool isEqual x a b c | (x == a) = True | (x == b) = True | (x == c) = True | otherwise = False howManyOfFourEqual :: Int -> Int -> Int -> Int -> Int howManyOfFourEqual a b c d | isEqual a b c d = howManyEqual b c d + 1 | otherwise = howManyEqual b c d Pls. test it ;) Sincerely, Gour -- Registered Linux User | #278493 GPG Public Key | 8C44EDCD

I had a go with things along this theme and came up with a couple of options, with different type signatures. I use some functions from the Data.List library. If we know that, as with Ints, we are dealing with list members that are instances of Ord, we can do: howManyEqual :: (Eq a, Ord a) => [a] -> Int howManyEqual = maximum . (0 :) . map length . group . sort Otherwise, we end up less efficient, with: howManyEqual :: Eq a => [a] -> Int howManyEqual = countEach 0 where countEach best [] = best countEach best list@(x:_) = let (xs, others) = partition (== x) list in countEach (max (length xs) best) others -- Mark

Thanks to all the replies! It seems that there are ways to solve the exercise if I use constructs that are found in later chapters of the book. Sean could be right in that some of the exercises are meant to be difficult to solve and they prepare you for later chapters. Tried Gour's suggestion, but didn't work for howManyOfFourEqual 4 4 2 2 = 3 Anyway the approach was similar to mine, and if I use isEqual I could get a simpler solution. Thanks again. -- Kaoru Hosokawa khosokawa@gmail.com

Kaoru Hosokawa wrote:
Thanks to all the replies!
It seems that there are ways to solve the exercise if I use constructs that are found in later chapters of the book. Sean could be right in that some of the exercises are meant to be difficult to solve and they prepare you for later chapters.
As a programmer, I was unhappy with my answers to some of the earlier exercises because they were clearly inefficient and/or inelegant. This kept me reading the book, knowing the answers would present themselves. On more than one occasion I would fret for a few hours over an exercise and then a day or two later learn something new two chapters later which made the exercise much, much easier. Sometimes trivial. As an aside, I kept all of the exercises in revision control. So I can look back at what I first wrote and my later changes. A habit I plan to keep as I move on to other programming texts and languages.

Date: Sat, 12 Mar 2005 23:39:21 -0800 From: Sean Perry
Cc: Haskell-Cafe@haskell.org As an aside, I kept all of the exercises in revision control. So I can look back at what I first wrote and my later changes. A habit I plan to keep as I move on to other programming texts and languages.
That's a nice approach. But I can't resist asking: once you've learned Haskell, what is there left to move on to? ;-) Mike

Michael Vanier wrote:
Date: Sat, 12 Mar 2005 23:39:21 -0800 From: Sean Perry
Cc: Haskell-Cafe@haskell.org As an aside, I kept all of the exercises in revision control. So I can look back at what I first wrote and my later changes. A habit I plan to keep as I move on to other programming texts and languages.
That's a nice approach. But I can't resist asking: once you've learned Haskell, what is there left to move on to? ;-)
(-: I try to learn a new language every other year or so. Lisp and I have butted heads many times. So I thought I would try Haskell -- already love Python and the two are clearly siblings with divorced parents. Unfortunately since Haskell is neither C nor Perl, I will probably only dabble in it, much like Python. Not a fact I like, but one that the corporate world keeps making me swallow.

Date: Sun, 13 Mar 2005 00:01:17 -0800 From: Sean Perry
Cc: Michael Vanier wrote:
Date: Sat, 12 Mar 2005 23:39:21 -0800 From: Sean Perry
Cc: Haskell-Cafe@haskell.org As an aside, I kept all of the exercises in revision control. So I can look back at what I first wrote and my later changes. A habit I plan to keep as I move on to other programming texts and languages.
That's a nice approach. But I can't resist asking: once you've learned Haskell, what is there left to move on to? ;-)
(-:
I try to learn a new language every other year or so. Lisp and I have butted heads many times. So I thought I would try Haskell -- already love Python and the two are clearly siblings with divorced parents.
Unfortunately since Haskell is neither C nor Perl, I will probably only dabble in it, much like Python. Not a fact I like, but one that the corporate world keeps making me swallow.
Actually, haskell and python share little except some syntactic similarities. But haskell shares a lot with lisp/scheme. There are some good books on scheme e.g. SICP (http://mitpress.mit.edu/~sicp) and "How to Design Programs" (http://www.htdp.org) which would be very helpful for the beginning haskell programmer to absorb (you have to learn to walk before you can write monadic parser combinators ;-)). OTOH lisp and scheme are strict languages, like ocaml, unlike haskell, which is lazy. That makes a big difference in practice. As for C or Perl, try using haskell to generate C or Perl and don't tell your employers where the C/perl code came from ;-) Even though I'm just a haskell newbie myself, I think it's the most interesting language around, by a pretty wide margin. Mike
participants (6)
-
Andy Georges
-
Gour
-
Kaoru Hosokawa
-
Mark Carroll
-
Michael Vanier
-
Sean Perry