Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Haskell help, /prog/!

Name: Anonymous 2008-09-16 15:04


-- create a random tree.
randomTree :: Random r => IO (BinaryTree r)
randomTree =
     -- randomly pick the left and right sides.
  do leftIO  <- pick(randomLeaf, randomBranch)
     rightIO <- pick(randomLeaf, randomBranch)
     -- "un-IO" the sides.
     left    <- leftIO
     right   <- rightIO
     -- get a random value for the top of the branch/tree.
     value   <- randomIO
     -- create branch and return.
     return (Branch left value right)
  where
    -- return left or right at random.
    pick (left, right) =
      do useLeft <- randomRIO(True, False)
         if useLeft then return left else return right
    -- create a random leaf.
    randomLeaf =
      do value <- randomIO
         let leaf = Leaf value
         return leaf
    -- setup an alias.
    randomBranch = randomTree


This code actually works fine, but I'm wondering if there's a way to simplify the "leftIO/rightIO" stuff. Is there some sort of "double arrow" that will un-Monad twice, or is this verbosity unavoidable?

Name: Anonymous 2008-09-18 20:08

>>40
7

Name: Anonymous 2008-09-18 21:25

But what is the length() of a piece of String?

Name: Anonymous 2008-09-18 21:27

>>29
Sorry to disapoint you, but in this particular case the tree generation isn't lazy, because it's tied to the IO monad.

Name: Anonymous 2008-09-19 1:11

>>43

instance Random r => Random (BinaryTree r) where
  randomR (a, b) g = let (useA, g1) = random g in
                     if useA then (a, g1) else (b, g1)

  random g = let (leaf, g1) = random g in
             if leaf
               then let (value, g2) = random g1 in
                    (Leaf value, g2)
               else let (left,  g2) = random g1 in
                    let (right, g3) = random g2 in
                    let (value, g4) = random g3 in
                    (Branch left value right, g4)


There, no monads now. randomR doesn't really work like it's supposed to, but at least now there's no warnings.

Name: Anonymous 2008-09-19 10:17

>>44
I like monads.

import Control.Monad.State
import System.Random
import System

data BinaryTree a = Empty
                  | Node a (BinaryTree a) (BinaryTree a)
           deriving Show

randomS :: (RandomGen s, Random a) => State s a
randomS = State random

randomRS :: (RandomGen s, Random a) => (a, a) -> State s a
randomRS = State . randomR

randomTree :: (RandomGen s, Random a) => State s (BinaryTree a)
randomTree = ([return Empty, randomNode] !!) =<< randomRS (0, 1)

randomNode :: (RandomGen s, Random a) => State s (BinaryTree a)
randomNode = liftM3 Node randomS randomTree randomTree

instance Random a => Random (BinaryTree a) where
   --random = runState randomTree
   random = runState randomNode

prune 0 _ = Empty
prune height tree
   | height < 0 = error "prune: height must be non-negative"
   | otherwise =
        case tree of (Node v l r) -> Node v (ascend l) (ascend r)
                     Empty        -> Empty
   where ascend = prune (height - 1)

main = print =<< liftM2 prune (fmap (read . head) getArgs)
                              (randomIO :: IO (BinaryTree Int))

Name: Anonymous 2008-09-19 10:25

One of these days I need to set aside a week or so, hike out into the mountains with a copy of the Haskell documentation and just spend the week in quiet meditation reading and completing the exercises until I have some comprehension of this strange and wonderful language.

Name: Anonymous 2008-09-19 10:40

>>46
The Sussman?

Name: Anonymous 2008-09-19 16:29

Name: Anonymous 2008-09-20 9:18

http;//ATS.com/ats

Name: Anonymous 2008-09-20 12:03

I don't feel that it's a big question, so I'll ask here instead of making a new thread;

I want to make a list of each possible result of multiplying two-digit numbers. I can do it like this:

foo = [x*y | x <- [10..99], y <- [10..99]]

but how would I do it using double map? I mean a trick like this:

foo = map (map (\x -> (\y -> y*x)) [10..99]) [10..99]

except a working one.

Name: Anonymous 2008-09-20 12:06

I meant

foo = [x*y | x <- [10..99], y <- [x..99]]

Name: Anonymous 2008-09-20 12:29

in ATS you could write

let foo = cproduct (ditto 10 99) (fn x => ditto x 99)

Name: Anonymous 2008-09-20 12:47

>>50
[code=haskell]
foo = concatMap (\x->map (x*) [10..99]) [10..99]
[/code]

or

[code=haskell]
foo = concatMap (flip map [10..99] . (*)) [10..99]
[/code]

>>51

[code=haskell]
foo = concatMap (\x->map (x*) [x..99]) [10..99]
[/code]

Name: Anonymous 2008-09-20 12:59

>>51
foo = [10..99] >>= \x -> map (x*) [x..99]

Name: Anonymous 2008-09-20 13:44

>>51
liftM2 (*) [10 .. 99] [10 .. 99]

Name: Anonymous 2008-09-20 13:49

Now you fib(10) problems.

Name: Anonymous 2008-09-20 13:56

>>55
nub $ liftM2 (*) [10 .. 99] [10 .. 99]

Name: Anonymous 2008-09-20 16:50

>>56
I think you mean ``(fib 10)'' problems.

Name: Anonymous 2008-09-20 20:48

>>58
Now you have... fuck this.

Name: Anonymous 2008-09-21 11:01

>>43,44
Despite the tree generation now being lazy, pruning a resulting tree still wouldn't guarantee termination upon printing. That's because each node's generation depends on state created by the generation of all nodes to its left. For pruning to do what's expected you have to split the random generator before each recursion in the tree generation.

import Control.Monad.State
import Control.Arrow
import System.Random
import System

data BinaryTree a = Empty
                  | Node a (BinaryTree a) (BinaryTree a)
           deriving Show

randomRS :: (RandomGen g, Random a) => (a, a) -> State g a
randomRS bounds = State $ randomR bounds

splitS :: RandomGen g => State g a -> State g a
splitS fork = State $ first (evalState fork) . split

randomTreeS :: (RandomGen g, Random a, Eq a) => (a, a) -> State g (BinaryTree a)
randomTreeS bounds@(l, r)
   | l == r = return Empty
   | otherwise = do v <- randomRS bounds
                    splitS $ liftM2 (Node v) (randomTreeS (l, v)) 
                                             (randomTreeS (v, r))

instance (Random a, Bounded a, Eq a) => Random (BinaryTree a) where
   randomR = error "randomR: (BinaryTree a) does not implement this method"
   random = runState $ randomTreeS (minBound, maxBound)

prune :: Integral i => i -> BinaryTree a -> BinaryTree a
prune 0 _ = Empty
prune height tree
   | height < 0 = error "prune: height must be non-negative"
   | otherwise =
        case tree of Node v l r -> Node v (ascend l) (ascend r)
                     Empty      -> Empty
   where ascend = prune (height - 1)

main :: IO ()
main = print =<< liftM2 prune (fmap (read . head) getArgs)
                              (randomIO :: IO (BinaryTree Int))

Name: Anonymous 2008-09-21 12:38

>>58
Now you have used a faggot quotes

Name: Anonymous 2008-09-21 15:50

>>60 was actually meant to quote >>44,45

Name: Anonymous 2008-09-22 16:52

I can't believe that /prog/ is actually being helpful to someone.

Name: Anonymous 2008-09-22 21:33

>>63
I agree. We must put a stop to this immediately.

Name: Anonymous 2008-09-23 0:49

>>64
I didn't help >>1, and I don't know who of you or the Sussman did it, but let me tell you this much: anii will be haxed tonight.

Name: Anonymous 2010-11-27 10:21

Name: Anonymous 2010-12-17 1:19

Are you GAY?
Are you a NIGGER?
Are you a GAY NIGGER?

If you answered "Yes" to all of the above questions, then GNAA (GAY NIGGER ASSOCIATION OF AMERICA) might be exactly what you've been looking for!

Name: Anonymous 2010-12-17 1:37

This post brought to you by the Gay Nigger Association of America

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List