![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
Haskell
Does anyone have any experience with Haskell?
I've been trying to learn the language (based on the principle that if you can learn Haskell, you can learn anything), and I've been writing a number of small programs to help me learn. One of the programs is a module that implements a bag data structure (similar to a set, but keeps track of the amounts of each item). I've been trying to construct a function to give me a sub-bag of the N most common elements, but I have yet to have much luck. Here's what I have so far: module Bag where
import Data.Map as Map
type Bag a = Map a Int
fromList :: Ord a => [a] -> Bag a
fromList [] = Map.empty
fromList (x:xs) = Map.insertWith (+) x 1 (Bag.fromList xs)
mostCommon :: Int -> Bag a -> Bag a
{- How to implement this function ... -} |
|
|
|
|
|
#2 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
For those interested, here's a working (if limited) bag module:
module Bag where import Data.Map as Map import List -- A bag is a specialised type of map type Bag a = Map a Int -- Creates a bag from a list fromList :: Ord a => [a] -> Bag a fromList [] = Map.empty fromList (x:xs) = Map.insertWith (+) x 1 (Bag.fromList xs) -- Compares the latter value of two tuples compareAmounts :: Ord b => (a,b) -> (a,b) -> Ordering compareAmounts (_,x) (_,y) = compare x y -- Creates an ordered list from a bag toAscList :: Ord a => Bag a -> [(a, Int)] toAscList = (sortBy compareAmounts) . Map.toList -- Returns the most common elements in the bag mostCommon :: Ord a => Int -> Bag a -> Bag a mostCommon n = Map.fromList . (Map.foldWithKey maximumValues []) where maximumValues k v maxs = take n (insertValues k v maxs) insertValues k v = insertBy (flip compareAmounts) (k,v) |
|
|
|
|
|
#3 |
|
Newbie
Join Date: Jan 2006
Posts: 20
Rep Power: 0
![]() |
Clean (http://www.cs.ru.nl/%7Eclean/index.html) is also an interesting language to check out, I was learning this for a while, it's based on Haskell for the most part but adds other functional programming concepts including some features not found in other languages.
|
|
|
|
|
|
#4 |
|
The Oblivious One
Join Date: May 2005
Location: Ontario, Canada
Posts: 641
Rep Power: 4
![]() |
Arevos, I've been bored lately so I took up your challenge. This is the beginnings of a card module I wrote after reading for about 3-4 hours. At this point, I don't really understand monads, but I think I'm doing the random stuff correctly.
Cards.hs -- Written by Jessehk on
-- Monday December 11, 2006
module Cards
where
import System.Random
data Card = Card Face Suit
| Joker
deriving (Show, Eq)
data Suit = Hearts
| Diamonds
| Clubs
| Spades
deriving (Show, Eq)
suits :: [Suit]
suits = [Hearts, Diamonds, Clubs, Spades]
data Face = Jack
| Queen
| King
| Ace
| Number Int
deriving (Show, Eq)
faces :: [Face]
faces = [Number 2 , Number 3, Number 4, Number 5,
Number 6 , Number 7, Number 8, Number 9,
Number 10, Jack , Queen , King ,
Ace]
-- Return a list of all cards of a given Suit.
allOfSuit :: Suit -> [Card]
allOfSuit = cardsFromList . (zip faces) . repeat
deck :: [Card]
deck = (concat . map allOfSuit) suits
-- Return a List of cards from a List of tuples.
cardsFromList :: [(Face, Suit)] -> [Card]
cardsFromList [] = []
cardsFromList ((face, suit) : xs) = Card face suit : cardsFromList xs
shuffle :: [Card] -> IO [Card]
shuffle [] = return []
shuffle cards = do
card <- randCard cards
rest <- shuffle $ filter (/= card) cards
return (card : rest)
randCard :: [Card] -> IO Card
randCard cards = do
numb <- randomRIO (0 :: Int, length cards - 1)
return $ cards !! numbMain.hs module Main
where
import Cards
main = do
shuffled <- shuffle deck
(putStrLn . show . length) shuffled
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS! Last edited by Jessehk; Dec 11th, 2006 at 10:29 PM. |
|
|
|
|
|
#5 | ||
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
Quote:
- I'm especially impressed with your use of the IO monad. I had all sorts of problems with that.Quote:
I found monads are tricky not because they're inherently complex, but because they're such a generic concept it's difficult to relate them back to practical problems. The You-Could-Have article neatly bridges that gap, I discovered. |
||
|
|
|
|
|
#6 |
|
The Oblivious One
Join Date: May 2005
Location: Ontario, Canada
Posts: 641
Rep Power: 4
![]() |
Thanks for the article, I'll have a look.
![]() Haskell is interesting, but any idea that somebody with not a lot of programming experience could learn on Haskell is just wrong (IMO). For a start, the standard library documentation is very unforgiving (very little hand-holding).
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS! |
|
|
|
|
|
#7 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
You may be correct; I'm certainly having to do some mental adjustment. In the absence of documentation, you're certainly right.
On the other hand, learning to solve problems without the overhead of preconceptions coming from non-functional languages may make learning from scratch no more difficult than learning to solve problems using other languages. Low level procedural languages are certainly not a good match for our natural, more abstract mental processes.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#8 | |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
Quote:
For instance, previously, I wrote a mostCommon function using standard functional techniques, such as fold and filter. However, now I can't help wondering if I couldn't create a simpler, more abstract function by making use of all the functions in Haskell that operate upon monads. I'll try and see if it's possible to come up with something better. I think the attraction of Haskell is not so much that it is functional, but because it enables developers to play around with very abstract concepts in a way other languages can't easily match. It's my opinion that a lot of what makes a good programmer good is his or her ability to think abstractly about a problem. For instance, a beginner who wanted to calculate the first 10 fibonacci numbers might do something like this: def fib(n):
a = 1
b = 1
print a
print b
for i in range(n):
c = a + b
a = b
b = c
print b
fib(10)def fib(n):
s = [1, 1]
for i in xrange(n):
s.append(sum(s))
yield s.pop(0)
for x in fib(10): print xfib = 1 : 1 : zipWith (+) fib (tail fib) main = mapM (putStrLn . show) (take 10 fib) ![]() |
|
|
|
|
|
|
#9 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
To me, the recursion seems somewhat natural. The idea that you can apply a function to something that reapplies it after making a step variation by some means seems neat. I'm still very raw with it, but I'm thinking of applying it to the tic tac toe game, as a learning exercise. Because the number of possible moves (especially when reduced by the idea of equivalence) is not terribly large, the lazy sequence wouldn't be infinite, but would terminate after nine moves or when a win or draw was detected. No pruning, ala chess, should be necessary -- the end should be reachable without resorting to pruning. This means that the outcome is a distinct value, and not a guess or approximation based on some set of evaluation rules. This thing of highly modular functions that can be composed into more complex functions, applicable to varying types, is just intriguing to me. I haven't messed with Lisp since the early 90s, but the notion of the Haskell list is distinctly familiar.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#10 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
I'm used to recursion in functions, but using recursion to definite an infinite sequence seems rather odd, somehow. Elegant and precise, certainly, but still a little unusual.
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|