Programming Forums
User Name Password Register
 

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

Reply
 
Thread Tools Display Modes
Old May 30th, 2007, 7:07 PM   #21
Jessehk
The Oblivious One
 
Jessehk's Avatar
 
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4 Jessehk is on a distinguished road
Ok, I consulted the excellent people on #haskell, and I filled in a few gaps in my knowledge and understanding.

(c, d') <- lift $ randCard d

If you think of a monad as being m a, then
what lift actually does here is create a new monad where m is has the type StateT Deck IO and a, the data, is just the (Card, Deck) tuple.

So, (c, d') is just the card, and the new deck.
You put in the new state,
and by returning c, you encapsulate the card in a StateT Deck IO monad.

I also realized I didn't go over dealCards.
dealCards :: Int -> StateT Deck IO [Card]
dealCards n = replicateM n dealCard

replicateM takes an integer, and a monad, and creates m [a] array consisting of that many things.

For example,
$ ghci 
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.6, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Prelude> :m + Control.Monad
Prelude Control.Monad> let foo = return 3 :: IO Int
Prelude Control.Monad> let c = replicateM 10 foo
Prelude Control.Monad> :t c
c :: IO [Int]
Prelude Control.Monad> c
[3,3,3,3,3,3,3,3,3,3]
Prelude Control.Monad>
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS!
Jessehk is offline   Reply With Quote
Old May 31st, 2007, 9:21 AM   #22
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Okay, I believe I understand now, but I'll go over my understanding for the benefit of others (and myself!).

The State monad has the type signature of:
newtype State s a = State { runState :: (s -> (a, s)) }
Which is simple enough. The state is s, and State s a represents the function s -> (a, s). In other words, a transition from an initial state to a return value and finishing state.

The StateT monad is similar, but wraps the output in an internal monad, m:
newtype StateT s m a = StateT { runStateT :: (s -> m (a, s)) }
In this case, m is IO.

Now, it occurs to me that randCard follows the same type signature as runStateT:
runStateT :: s -> m (a, s)
randCard  :: Deck -> IO (Card, Deck)
So randCard could be rewritten as:
randCard :: StateT Deck IO Card
And it would mean essentially the same thing. This means there's no need to separate randCard and dealCard. Instead:
dealCard :: StateT Deck IO Card
dealCard = do
    cards <- get
    n     <- randomRIO (0 :: Int, length cards - 1)
    let card = cards !! n
    put $ delete card cards
    return card
And in theory, it would have the same functionality. Maybe even split out the random choice functionality to make it more generic:
randomChoice :: [a] -> IO a
randomChoice xs = do
    n <- randomRIO (0 :: Int, length xs - 1)
    return xs !! n

dealCard :: StateT Deck IO Card
dealCard = do
    cards <- get
    let card = randomChoice cards
    put $ delete card cards
    return card
I haven't tested any of these functions out, as I currently don't have access to a Haskell compiler or interpreter, but the basic idea seems sound... I hope!
Arevos is offline   Reply With Quote
Old May 31st, 2007, 5:05 PM   #23
Jessehk
The Oblivious One
 
Jessehk's Avatar
 
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4 Jessehk is on a distinguished road
How accurate would I be if I were to suggest that you knew all of this prior to my explanation and it was in fact a test of my knowledge?
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS!
Jessehk is offline   Reply With Quote
Old Jun 1st, 2007, 5:46 AM   #24
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 Jessehk View Post
How accurate would I be if I were to suggest that you knew all of this prior to my explanation and it was in fact a test of my knowledge?
Not at all! It just took me a while to puzzle it all out. I've never really used the State monad before, and I've never even seen the StateT monad, so it was only after your explanation that I understood what it was you were doing. In fact, I still don't understand monad transformers that well!

But once you'd gone over it, I looked up the functions and types you used for further reading, and after a while I understood enough to suggest a refactoring of dealCard. But just looking up the type signatures of Haskell functions is often not that useful - your explanation helped me get it all straight in my head
Arevos is offline   Reply With Quote
Old Jun 2nd, 2007, 10:42 PM   #25
Jessehk
The Oblivious One
 
Jessehk's Avatar
 
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4 Jessehk is on a distinguished road
You know, Hasell is definitely elegant and fun. I think problem is that it's too smart -- most code is too clever and confusing (despite being fun and interesting).

I've been looking again at ocaml, and it really looks like a practical haskell.

With an emphasis on safety, speed, and practicality (it includes imperative features when required), I think it's definitely the more viable of the two languages.

Plus, it's got several features that may not be immediately obvious (they just don't market themselves well). Complete bindings to openGL, Gtk+, GNOME, several libraries, a byte-code compiler, and a native code compiler, a profiler, a debugger (ocamldebug), a parser/syntax-modifier thingy (campl4), a package-manager (ocamlfind), and a documentation generator (ocamldoc).

I know my opinion is largely based on observation and not experience (I'm still in high school), but it looks like engineers, scientists, and developers could actually write useful programs today using ocaml.
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS!
Jessehk is offline   Reply With Quote
Old Jun 3rd, 2007, 4:34 PM   #26
Mad_guy
Hobbyist Programmer
 
Mad_guy's Avatar
 
Join Date: Oct 2004
Location: Sandstorm, Techno Club
Posts: 239
Rep Power: 4 Mad_guy is on a distinguished road
Send a message via AIM to Mad_guy Send a message via MSN to Mad_guy
This is just back to the previous topic, I found the easiest way to understand Monad Transformers is a basic Onion Layer analogy.

Essentially, you have your monad x, and a second monad y. x is your 'outer layer,' while y is your 'inner layer.' Your transformer itself in the context of x, while you can 'lift' operations down a layer (into the combined monad.) For example:

import Control.Monad.State

trans :: StateT Int IO () 
trans = do
	modify (+1)
	lift $ putStrLn "in monad transformer trans"
	return ()

This is wrapping State around IO to create your combined Monad. In this case, your expressions in your do construct must obey the laws of the StateT transformer (in the case of how expressions are changed; you aren't in the IO monad anymore.)

To execute this state, you have three functions:

*Main> :t runStateT
runStateT :: StateT s m a -> s -> m (a, s)
*Main> :t execStateT
execStateT :: (Monad m) => StateT s m a -> s -> m s
*Main> :t evalStateT
evalStateT :: (Monad m) => StateT s m a -> s -> m a
*Main>

So here's the example:
*Main> runStateT trans 0
Loading package mtl-1.0 ... linking ... done.
in monad transformer trans
((),1)
*Main>


Using Monad Transformers you can combine monads for more side effects if you need them in your functions. Note that you cannot wrap IO (it will always form your 'innermost monad.') Generally I've found StateT to be one of the easiest Transformers to use.

Also note, anything run in the context of a transformer can access the monads regardless if they were called directly by those *StateT functions, or they were called by others.
__________________
os: mac os 10.5.4
revision control: git
editor: emacs

site
Mad_guy 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




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

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