![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#21 |
|
The Oblivious One
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4
![]() |
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! |
|
|
|
|
|
#22 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
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)) }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)) }Now, it occurs to me that randCard follows the same type signature as runStateT: runStateT :: s -> m (a, s) randCard :: Deck -> IO (Card, Deck) randCard :: StateT Deck IO Card 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 cardrandomChoice :: [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![]() |
|
|
|
|
|
#23 |
|
The Oblivious One
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4
![]() |
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! |
|
|
|
|
|
#24 | |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
Quote:
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 ![]() |
|
|
|
|
|
|
#25 |
|
The Oblivious One
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4
![]() |
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! |
|
|
|
|
|
#26 |
|
Hobbyist Programmer
|
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. |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|