Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  Re: permuting a list (Felipe Lessa)
   2.  Re: permuting a list (Heinrich Apfelmus)
   3. Re:  Re: permuting a list (Daniel Fischer)
   4.  Re: permuting a list (Heinrich Apfelmus)
   5. Re:  Re: permuting a list (Daniel Fischer)
   6.  Re: permuting a list (Jon Fairbairn)
   7.  Re: [Haskell-cafe] Re: permuting a list (Alberto Ruiz)
   8.  Re: [Haskell-cafe] Re: permuting a list (Felipe Lessa)
   9.  Re: [Haskell-cafe] Re: permuting a list (Paul Johnson)
  10.  Re: permuting a list (Henning Thielemann)


----------------------------------------------------------------------

Message: 1
Date: Fri, 13 Feb 2009 08:03:27 -0200
From: Felipe Lessa <[email protected]>
Subject: Re: [Haskell-beginners] Re: permuting a list
To: Daniel Fischer <[email protected]>
Cc: [email protected], [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=UTF-8

On Fri, Feb 13, 2009 at 7:56 AM, Daniel Fischer
<[email protected]> wrote:
> You need the forall a to bring the type variable a into scope. Without it, the
> a in
>
> arr0 <- (newListArray (0, n) xs :: IO (IOArray Int a))
>
> would be implicitly universally quantified, too, and you would say that all
> elements of xs had type (forall b. b), which means all are _|_.
> Having brought the a from permute's type signature into scope, the a in the
> above line is the *same* a as the one in permute's type signature.

Whoops, sorry about that, didn't see that ScopedTypeVariables was active. :)

-- 
Felipe.


------------------------------

Message: 2
Date: Fri, 13 Feb 2009 11:25:04 +0100
From: Heinrich Apfelmus <[email protected]>
Subject: [Haskell-beginners] Re: permuting a list
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-15

Jan Snajder wrote:
> Brent Yorgey wrote:
> 
>> The problem seems to be that
>> Haskell has no way to know what sort of array you want to use.  I was
>> able to get the code to work, but it's sort of sneaky:
>>
>>> {-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}
>>>
>>> import Data.Array.MArray
>>> import Data.Array.IO
>>> import Control.Monad
>>> import System.Random
>>> permute :: forall a. (MArray IOArray a IO) => [a] -> IO [a]
>>> permute xs = do
>>>   let n = length xs - 1
>>>   arr0 <- (newListArray (0, n) xs :: IO (IOArray Int a))
>>>   arr <- foldM swap arr0 [n..1]
>>>   getElems arr
>>>   where swap arr n = do
>>>           x <- readArray arr n
>>>           r <- randomRIO (0, n)
>>>           y <- readArray arr r
>>>           writeArray arr n y
>>>           writeArray arr r x
>>>           return arr

The type class constraint is not needed because IOArray can hold any
element type anyway. (It's unboxed arrays that only work for certain
element types). Thus, you can write  FlexibleConstraints  extension and
simply write

  permute :: forall a. [a] -> IO [a]

instead.

Also, I think that specifying the type of  arr0  as

  (arr0 :: IOArray Int a) <- newListArray (0, n) xs

should work as well.


-- 
http://apfelmus.nfshost.com



------------------------------

Message: 3
Date: Fri, 13 Feb 2009 11:30:34 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Re: permuting a list
To: [email protected], [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="iso-8859-15"

Am Freitag, 13. Februar 2009 10:23 schrieb Jan Snajder:
> Brent Yorgey wrote:
> > It seems everyone has just been reading the first few words of Jan's
> > email and not the actual content.  Jan is clearly trying to write a
> > *random list shuffling* function, not a function to generate
> > permutations.  Let's try to be helpful, people...
> > </rant>
>
> Thanks Brant, I forgot to mention explicitly that I need a random
> permutation.
>
> > Jan, this is tricky.  The type of permute is indeed (MArray a1 a IO)
> > => [a] -> IO [a], but this is fine, it just means that there has to be
> > some sort of mutable array which can store the things you are trying
> > to shuffle.
> >   This is not the problem.  The problem seems to be that
> > Haskell has no way to know what sort of array you want to use.  I was
> >
> > able to get the code to work, but it's sort of sneaky:
> > > {-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}
>
> I guess by 'sneaky' you mean this solution is GHC-specific?

It can be made a little less sneaky, you don't need FlexibleContexts, because 
the type signature

permute :: forall a. [a] -> IO [a]

works, too (code otherwise unchanged). 
But that still doesn't work with hugs :(

However, if you bring the array-creation to top level, it doesn't need any 
module-specific language extensions:

module Perms where

import Data.Array.MArray
import Data.Array.IO
import Control.Monad
import System.Random

-- call with toArray (length xs - 1) xs
toArray :: Int -> [a] -> IO (IOArray Int a)
toArray n xs = newListArray (0,n) xs

permute :: [a] -> IO [a]
permute xs = do
    let n = length xs - 1
    arr0 <- toArray n xs
    arr <- foldM swap arr0 [n, n-1 .. 1]
    getElems arr
  where
      swap arr n = do
        x <- readArray arr n
        r <- randomRIO (0, n)
        y <- readArray arr r
        writeArray arr n y
        writeArray arr r x
        return arr

and it works in hugs, too (needs the -98 flag, because one of the imports 
needs ST.hs, which has foralled type signatures).

Cheers,
Daniel


------------------------------

Message: 4
Date: Sat, 14 Feb 2009 16:37:44 +0100
From: Heinrich Apfelmus <[email protected]>
Subject: [Haskell-beginners] Re: permuting a list
To: [email protected]
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Daniel Fischer wrote:
> Thomas Davie wrote:
>> Brent Yorgey wrote:
>>> Andrew Wagner wrote:
>>>> Brent Yorgey wrote
>>>>> <rant> It seems everyone has just been reading the first few
>>>>> words of Jan's email and not the actual content.  Jan is
>>>>> clearly trying to write a *random list shuffling* function,
>>>>> not a function to generate permutations.  Let's try to be
>>>>> helpful, people... </rant>
>>>> 
>>>> Agreed, I've been quite confused by this thread. In the spirit
>>>> of laziness, though, wouldn't it seem like the "right" method
>>>> is to generate all the permutations lazily, and then choose a
>>>> random element of that list?
>>> 
>>> Well, it sounds nice, but it's pretty inefficient.  And by
>>> "pretty inefficient" I mean "horrendously, terribly inefficient"
>>> -- there are n! permutations of a list of length n, so this would
>>> take time O(n!) as opposed to O(n); O(n!) is even worse than
>>> O(2^n).
>> 
>> Would it?  We're talking about lazyness here... it's not gonna
>> compute one it doesn't need, and if you're somewhat cleverer with
>> your permute function than I was, I'm sure you can do as little
>> computation as the imperative version.
> 
> But to find the k-th permutation, it would have to traverse k cons
> cells containing thunks, wouldn't it?
> 
> Well, the following is O(n^2), not quite O(n), but at least it's not
>  "horrendously, terribly inefficient".

That of course begs the question whether there is a faster but purely
functional algorithm for generating random permutations without indexes
and arrays?

The answer is a resounding "yes" and the main idea is that shuffling a
list is *essentially the same* as sorting a list; the minor difference
being that the former chooses a permutation at random while the latter
chooses a very particular permutation, namely the one that sorts the input.

For the full exposition, see

   http://apfelmus.nfshost.com/random-permutations.html


Regards,
apfelmus

-- 
http://apfelmus.nfshost.com



------------------------------

Message: 5
Date: Sat, 14 Feb 2009 17:46:52 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Re: permuting a list
To: Heinrich Apfelmus <[email protected]>,
        [email protected]
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="iso-8859-1"

Am Samstag, 14. Februar 2009 16:37 schrieb Heinrich Apfelmus:
>
> That of course begs the question whether there is a faster but purely

No, it didn't beg any question. (Sorry for being a humourless pedant here)

> functional algorithm for generating random permutations without indexes
> and arrays?
>
> The answer is a resounding "yes" and the main idea is that shuffling a
> list is *essentially the same* as sorting a list; the minor difference
> being that the former chooses a permutation at random while the latter
> chooses a very particular permutation, namely the one that sorts the input.
>
> For the full exposition, see
>
>    http://apfelmus.nfshost.com/random-permutations.html

Excellent work, thanks.
>
>
> Regards,
> apfelmus

Cheers,
Daniel


------------------------------

Message: 6
Date: Sun, 15 Feb 2009 11:10:28 +0000
From: Jon Fairbairn <[email protected]>
Subject: [Haskell-beginners] Re: permuting a list
To: [email protected]
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8

Heinrich Apfelmus <[email protected]> writes:

> The answer is a resounding "yes" and the main idea is that shuffling a
> list is *essentially the same* as sorting a list; the minor difference
> being that the former chooses a permutation at random while the latter
> chooses a very particular permutation, namely the one that sorts the input.
>
> For the full exposition, see
>
>    http://apfelmus.nfshost.com/random-permutations.html

I haven't been following the thread, but my initial reaction
would have been something like use System.Random.randoms to
get a list rs and then do (roughly)

randomPerm = map snd . sortBy (compare `on` fst) . zip rs

How bad is that? I mean, how unfair does it get?

-- 
Jón Fairbairn                                 [email protected]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2009-01-31)



------------------------------

Message: 7
Date: Sun, 15 Feb 2009 13:22:51 +0100
From: Alberto Ruiz <[email protected]>
Subject: [Haskell-beginners] Re: [Haskell-cafe] Re: permuting a list
To: Heinrich Apfelmus <[email protected]>
Cc: [email protected], [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed

Heinrich Apfelmus wrote:
> Jon Fairbairn wrote:
>> Heinrich Apfelmus writes:
>>
>>> The answer is a resounding "yes" and the main idea is that shuffling a
>>> list is *essentially the same* as sorting a list; the minor difference
>>> being that the former chooses a permutation at random while the latter
>>> chooses a very particular permutation, namely the one that sorts the input.
>>>
>>> For the full exposition, see
>>>
>>>    http://apfelmus.nfshost.com/random-permutations.html
>> I haven't been following the thread, but my initial reaction
>> would have been something like use System.Random.randoms to
>> get a list rs and then do (roughly)
>>
>> randomPerm = map snd . sortBy (compare `on` fst) . zip rs
>>
>> How bad is that? I mean, how unfair does it get?
> 
> It's fair, but may duplicate elements, i.e. it doesn't necessarily
> create a permutation. For example,  rs  could be something like
> 
>    rs = [5,3,3,3,2,4]
> 

How about using random doubles?

randomPerm xs = fmap (map snd . sort . flip zip xs) rs
     where rs = fmap (randoms . mkStdGen) randomIO :: IO [Double]


------------------------------

Message: 8
Date: Sun, 15 Feb 2009 10:23:57 -0200
From: Felipe Lessa <[email protected]>
Subject: [Haskell-beginners] Re: [Haskell-cafe] Re: permuting a list
To: Heinrich Apfelmus <[email protected]>
Cc: [email protected], [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=UTF-8

On Sun, Feb 15, 2009 at 9:47 AM, Heinrich Apfelmus
<[email protected]> wrote:
> It's fair, but may duplicate elements, i.e. it doesn't necessarily
> create a permutation. For example,  rs  could be something like
>
>   rs = [5,3,3,3,2,4]
>

But our sort doesn't discard values when the keys are the same. For example,

[1,2,3,4] == map snd . sortBy (compare `on` fst) . zip (repeat 1) $ [1,2,3,4]

Nothing gets duplicated. Or did I miss something?

-- 
Felipe.


------------------------------

Message: 9
Date: Sun, 15 Feb 2009 15:05:21 +0000
From: Paul Johnson <[email protected]>
Subject: [Haskell-beginners] Re: [Haskell-cafe] Re: permuting a list
To: Alberto Ruiz <[email protected]>
Cc: Heinrich Apfelmus <[email protected]>,
        [email protected],  [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed

See http://okmij.org/ftp/Haskell/perfect-shuffle.txt

Paul.


------------------------------

Message: 10
Date: Sun, 15 Feb 2009 01:04:32 +0100 (CET)
From: Henning Thielemann <[email protected]>
Subject: [Haskell-beginners] Re: permuting a list
To: Daniel Fischer <[email protected]>
Cc: Heinrich Apfelmus <[email protected]>,
        [email protected],  [email protected]
Message-ID:
        <alpine.deb.2.00.0902150103030.32...@anubis.informatik.uni-halle.de>
Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed


On Sat, 14 Feb 2009, Daniel Fischer wrote:

> Am Samstag, 14. Februar 2009 16:37 schrieb Heinrich Apfelmus:
>>
>> For the full exposition, see
>>
>>    http://apfelmus.nfshost.com/random-permutations.html
>
> Excellent work, thanks.

Interesting read.
  Btw. a further development of the PFP library is also on Hackage:
   http://hackage.haskell.org/cgi-bin/hackage-scripts/package/probability


------------------------------

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 8, Issue 12
****************************************

Reply via email to