Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Oct 17th, 2006, 6:21 AM   #1
BungalowBill
Programmer
 
Join Date: Dec 2005
Posts: 40
Rep Power: 0 BungalowBill is on a distinguished road
Anyone with knowledge of Haskell?

Does anyone have any knowledge of using Haskell? I'm trying to write some functions to do some simple tasks.

For example, a program, getelem, which is given an integer n and a list, returns the nth element of the list. e.g.

Main> getelem 4 [1,2,3,4,5]
4

is what i hope the outcome would be. I understand there is a built in function !! that does this but i want to do it without using it. Can anyone offer any help?
BungalowBill is offline   Reply With Quote
Old Oct 17th, 2006, 7:57 AM   #2
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
My haskell isn't great, but you need to approach this problem from a recursive standpoint. Firstly, consider the limiting case; the set of arguments that will stop the recursion.

In this case, if n is 0, then all we have to do is return the beginning of the list (assuming that you want the first element to have an index of 0, rather than 1):
getelem 0 x:xs = x
So far so good? Now that the limiting case has been created, we want the general case. We want to define the general case in terms of itself, in a way that approaches the limiting case. So first, we want n to approach 0. Second, we want the list to be cut until the head of the list is the element we want. To put this in code:

getelem n x:xs = getelem (n - 1) xs

So your final function definition should look like:
getelem :: Integer -> [a] -> a
getelem 0 x:xs = x
getelem n x:xs = getelem (n - 1) xs
Note that I do not currently have access to a Haskell compiler, but hopefully my code should be syntaxically correct.

Last edited by Arevos; Oct 17th, 2006 at 8:40 AM. Reason: getelem 1 should be getelem 0
Arevos is offline   Reply With Quote
Old Oct 24th, 2006, 5:29 AM   #3
magnus.therning
Programmer
 
magnus.therning's Avatar
 
Join Date: May 2006
Location: Cambridge, UK
Posts: 88
Rep Power: 3 magnus.therning is on a distinguished road
You need some parentheses around the list pattern:

getelem 0 (x:xs) = x
getelem n (x:xs) = getelem (n - 1) xs

By terminating on 0 you have made the function count elements from 0, rather than from 1 (as was suggested in the original post). I think starting from 0 is a better choice though :-)
__________________
Don't comment bad code - rewrite it.
- The Elements of Programming Style (Kernighan & Plaugher)
magnus.therning is offline   Reply With Quote
Old Oct 24th, 2006, 6:08 AM   #4
BungalowBill
Programmer
 
Join Date: Dec 2005
Posts: 40
Rep Power: 0 BungalowBill is on a distinguished road
Hi thanks for the replys and sorry i haven't replied. The site wouldn't let me log back in for some reason. I tried logging in about 4 times and each time i went to post, it asked me to log in again. Anyway i cracked that one i think thanks a lot.

I do have another question now though. How would i go about declaring a list? For example a list of tuples like ((Jane,Mary), (Scott,Brian)) which would mean that Jane likes Mary or Scott likes Brian for example. Which i could then use at the terminal like this.

Main> likes "Scott" "Brian"
True

Any clue?
BungalowBill is offline   Reply With Quote
Old Oct 24th, 2006, 8:16 AM   #5
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Quote:
Originally Posted by magnus.therning
You need some parentheses around the list pattern
Whoops! You're quite correct!

Quote:
Originally Posted by BungalowBill
I do have another question now though. How would i go about declaring a list? For example a list of tuples like ((Jane,Mary), (Scott,Brian)) which would mean that Jane likes Mary or Scott likes Brian for example. Which i could then use at the terminal like this.
If I've understood you correctly, you want a hashtable of some kind. You can do this one of two ways. The most basic way is to define a list of tuples:
relationships = [("Jane", "Mary"), ("Scott", "Brian")]
And then to iterate through the entire list until you find a match. The long way of doing this would be:
inList :: Eq a => a -> [a] -> Bool
inList y (x:xs) = if y == x then True else (inList y xs)
inList y []     = False

likes a b xs = inList (a, b) xs

main = print (likes "Scott", "Brian", relationships)
Or you could do it using any:
likes a b xs = any (== (a, b)) xs
However, a more efficient way of doing this would be to use a set. As far as I'm aware, there isn't a standard set module for Haskell, but any decent Haskell implementation should have one in the standard library. For instance, GHC has Data.Set:
import Data.Set as Set

relationships = Set.fromList [("Jane", "Mary"), ("Scott", "Brian")]

likes a b s = Set.member (a, b) s
Because we're using a data type designed for this sort of work, the above allows for more efficient lookups than the standard iterative model.
Arevos is offline   Reply With Quote
Old Oct 24th, 2006, 9:26 AM   #6
BungalowBill
Programmer
 
Join Date: Dec 2005
Posts: 40
Rep Power: 0 BungalowBill is on a distinguished road
Thats almost it but not quite.

I want to set up a list like you said with
relationships = [("Jane", "Mary"), ("Scott", "Brian")]

but at the terminal all i want to type is the name of the function, two strings and a true or false indicating whether or not they are in the same tuple.
Like:

Main> likes "Scott" "Brian"
True

and it has to be order sensitive. So:

>Main likes "Brian" "Scott"
False

gives false. I think its going to get really complicated

One possible solution that im thinking of would be this. From the potential liked person(2nd person), you first of all compute all the people that directly like them (the 1st people). If the potential liker is in the list, return True. Otherwise, call the function recursively to see if one of the (1st people) is liked by the potential liker. Combine the results for the different likers together. If you understand what i mean. Using || maybe.

I'm just confusing myself now. That ^^^ made sense when i thought of it but now im not too sure.

Last edited by BungalowBill; Oct 24th, 2006 at 9:42 AM.
BungalowBill is offline   Reply With Quote
Old Oct 24th, 2006, 9:48 AM   #7
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Uh, then how about:
likes a b = any (== (a, b)) relationships
Or
likes a b = Set.member (a, b) relationships
Almost exactly the same function, but this time the relationships list is hard coded. Is that what you wanted?
Arevos is offline   Reply With Quote
Old Oct 24th, 2006, 1:04 PM   #8
BungalowBill
Programmer
 
Join Date: Dec 2005
Posts: 40
Rep Power: 0 BungalowBill is on a distinguished road
Yeah thanks that works great. For some reason i was thinking it was much more complicated that it was.

Now i'm attempting to create a noughts and crosses board.

I'll be back soon enough no doubt!

thanks.
BungalowBill is offline   Reply With Quote
Old Oct 26th, 2006, 10:52 AM   #9
BungalowBill
Programmer
 
Join Date: Dec 2005
Posts: 40
Rep Power: 0 BungalowBill is on a distinguished road
Hi im back again. This time with another question on something i've already asked about.

if i was to set up another list called companies. Like:

companies = [("c1, "c2"), ("c3", "c1"), ("c4", "c3")]

where the first one in each list is the company that is owned. the second company in eachlist is the one that owns the first. SO eventually i should be about to prove that c2 owns c4 indirectly. (because c2 owns c1, c1 owns c3, c3 owns c4. So c2 must own c4 indirectly.

If i were to give haskell two companies. the owned one and the owner, how would i compute all the companies that directly or indirectly own the potential owned company?
BungalowBill is offline   Reply With Quote
Old Oct 26th, 2006, 12:14 PM   #10
magnus.therning
Programmer
 
magnus.therning's Avatar
 
Join Date: May 2006
Location: Cambridge, UK
Posts: 88
Rep Power: 3 magnus.therning is on a distinguished road
Quote:
Originally Posted by BungalowBill View Post
Hi im back again. This time with another question on something i've already asked about.

if i was to set up another list called companies. Like:

companies = [("c1, "c2"), ("c3", "c1"), ("c4", "c3")]

where the first one in each list is the company that is owned. the second company in eachlist is the one that owns the first. SO eventually i should be about to prove that c2 owns c4 indirectly. (because c2 owns c1, c1 owns c3, c3 owns c4. So c2 must own c4 indirectly.

If i were to give haskell two companies. the owned one and the owner, how would i compute all the companies that directly or indirectly own the potential owned company?
I'm getting the distinct impression you are using this resource to get your home work done :-) I'm hoping for your sake you aren't and I don't think I'll bother with posting "full solutions" after this. This is my "solution":

ownPath2 :: [(String, String)] -> String -> String -> Maybe [(String, String)]
ownPath2 comps c1 c2 =
    let
        oP' [] _ = Nothing
        oP' ((d1, d2) : cs) s
            | s == d1 && c2 == d2 = Just [(d1, d2)]
            | s == d1 =
                case ownPath2 comps d2 c2 of
                    Just p -> Just ((d1, d2) : p)
                    Nothing -> oP' cs s
            | otherwise = oP' cs s
    in
        oP' comps c1
__________________
Don't comment bad code - rewrite it.
- The Elements of Programming Style (Kernighan & Plaugher)
magnus.therning is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Haskell Arevos Other Programming Languages 25 Jun 3rd, 2007 5:34 PM
General or Specific Knowledge? darthsabbath Coder's Corner Lounge 7 Jun 16th, 2006 3:54 PM
setting up apache on Ubuntu -- no knowledge whatsoever Jessehk Other Web Development Languages 18 Nov 3rd, 2005 8:26 PM
Mastery of one, or knowledge of many? Jessehk Coder's Corner Lounge 27 Sep 18th, 2005 11:05 AM
who here has sufficient knowledge of web programming, that could talk to me over aim? massive-war C++ 1 Apr 2nd, 2005 2:49 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 10:55 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC