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.  Help! Trapped in the IO Monad! (Erik de Castro Lopo)
   2. Re:  Help! Trapped in the IO Monad! (Andrew Wagner)
   3. Re:  Help! Trapped in the IO Monad! (Alexander Dunlap)
   4. Re:  To use random number monad inside function (Thomas Davie)
   5.  Re: To use random number monad inside function
      (Heinrich Apfelmus)
   6. Re:  Help! Trapped in the IO Monad! (Erik de Castro Lopo)
   7. Re:  Help! Trapped in the IO Monad! (Alexander Dunlap)


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

Message: 1
Date: Wed, 28 Jan 2009 15:07:01 +1100
From: Erik de Castro Lopo <[email protected]>
Subject: [Haskell-beginners] Help! Trapped in the IO Monad!
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII

Hi all,

I have a list of entries for a directory (FilePaths) and I'd like to
partition them into files and directories using Data.List.partition:

    partition :: [a] -> ([a], [a])

Now, one solution is to use unsafePerformIO:

    splitDirFile :: [FilePath] -> ([FilePath], [FilePath])
    splitDirFile paths = do
        partition (\p -> unsafePerformIO (doesDirectoryExist p)) paths

Two questions:

  a) Is it possible to do this without invoking unsafePerformIO? Ie with
     a function signature of say:

         partition :: [FilePath] -> IO ([FilePath], [FilePath])

  b) Exactly how unsafe is the unsafePerformIO version?

Erik
-- 
-----------------------------------------------------------------
Erik de Castro Lopo
-----------------------------------------------------------------
The main confusion about C++ is that its practitioners think
it is simultaneously a  high and low level language when in
reality it is good at neither.


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

Message: 2
Date: Tue, 27 Jan 2009 23:12:07 -0500
From: Andrew Wagner <[email protected]>
Subject: Re: [Haskell-beginners] Help! Trapped in the IO Monad!
To: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"

Hi Erik,The short answer to your question is to not write splitDirFile to
operate on FilePaths, but on some wrapper around FilePaths that also contain
information about whether each path is to a directory or a file. Then you
can call splitDirFile purely. For the long, but very good, answer, see RWH,
where they discuss this very specifically:
http://book.realworldhaskell.org/read/io-case-study-a-library-for-searching-the-filesystem.html

On Tue, Jan 27, 2009 at 11:07 PM, Erik de Castro Lopo
<[email protected]<mle%[email protected]>
> wrote:

> Hi all,
>
> I have a list of entries for a directory (FilePaths) and I'd like to
> partition them into files and directories using Data.List.partition:
>
>    partition :: [a] -> ([a], [a])
>
> Now, one solution is to use unsafePerformIO:
>
>    splitDirFile :: [FilePath] -> ([FilePath], [FilePath])
>    splitDirFile paths = do
>        partition (\p -> unsafePerformIO (doesDirectoryExist p)) paths
>
> Two questions:
>
>  a) Is it possible to do this without invoking unsafePerformIO? Ie with
>     a function signature of say:
>
>         partition :: [FilePath] -> IO ([FilePath], [FilePath])
>
>  b) Exactly how unsafe is the unsafePerformIO version?
>
> Erik
> --
> -----------------------------------------------------------------
> Erik de Castro Lopo
> -----------------------------------------------------------------
> The main confusion about C++ is that its practitioners think
> it is simultaneously a  high and low level language when in
> reality it is good at neither.
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090127/2d55812e/attachment-0001.htm

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

Message: 3
Date: Tue, 27 Jan 2009 20:14:27 -0800
From: Alexander Dunlap <[email protected]>
Subject: Re: [Haskell-beginners] Help! Trapped in the IO Monad!
To: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

You can do (something like; this is untested)

splitDirFile :: [FilePath] -> IO ([FilePath],[FilePath])
splitDirFile [] = return ([],[])
splitDirFile (f:fs) = do
  (yess,nos) <- splitDirFile fs
  exists <- doesDirectoryExist f
  return $ if exists
    then (f:yess,nos)
    else (yess,f:nos)

You might also look at Control.Monad.filterM. I often define a
function "partitionM" which is like partition except it uses a monadic
test, just like you have.

Alex

On Tue, Jan 27, 2009 at 8:07 PM, Erik de Castro Lopo
<[email protected]> wrote:
> Hi all,
>
> I have a list of entries for a directory (FilePaths) and I'd like to
> partition them into files and directories using Data.List.partition:
>
>    partition :: [a] -> ([a], [a])
>
> Now, one solution is to use unsafePerformIO:
>
>    splitDirFile :: [FilePath] -> ([FilePath], [FilePath])
>    splitDirFile paths = do
>        partition (\p -> unsafePerformIO (doesDirectoryExist p)) paths
>
> Two questions:
>
>  a) Is it possible to do this without invoking unsafePerformIO? Ie with
>     a function signature of say:
>
>         partition :: [FilePath] -> IO ([FilePath], [FilePath])
>
>  b) Exactly how unsafe is the unsafePerformIO version?
>
> Erik
> --
> -----------------------------------------------------------------
> Erik de Castro Lopo
> -----------------------------------------------------------------
> The main confusion about C++ is that its practitioners think
> it is simultaneously a  high and low level language when in
> reality it is good at neither.
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>


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

Message: 4
Date: Wed, 28 Jan 2009 08:23:07 +0100
From: Thomas Davie <[email protected]>
Subject: Re: [Haskell-beginners] To use random number monad inside
        function
To: Erick Gonz?lez <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="windows-1252"


On 28 Jan 2009, at 04:33, Erick González wrote:

> Hi:
> Haskell' s way of random number generation is strange to me, but I  
> know how to do that. I' d like to know how can I call random numbers  
> generated on the screen inside a classic function. I mean, I need to  
> know the way of calling random numbers (one different every time  
> that I run) inside a function. Please, Could anybody help me?

There's a problem with doing this – Haskell guarentees that no matter  
what (well, okay, not quite, but unsafePerformIO doesn't count), if  
you give the same arguments to a function, you'll get the same  
results.  This is known as referential transparency.  This is what  
gets us some of the biggest gains from the language (e.g. without it,  
we wouldn't be allowed to use our choice of non-strict evaluation  
order, we wouldn't be allowed to automatically parallelise, etc).

So, how is this problem solved?  In a couple of interesting ways.   
First is the way you've already seen, we can lock random number  
generation in a monad (usually the IO monad).  What this does, is it  
guarentees that the same IO action will always be returned by the  
function, but when that IO action gets shoved into the runtime, it can  
do any non-referentially transparent thing it likes, but that's  
"okay", because we're out of haskell land.

Understandably, this isn't the nicest way to do things, because it  
locks us in the IO monad, and in the evaluation of the action we lose  
all the advantages we had.  Not only that, but the programming style  
is fairly imperative.  So, we can think of a couple of ways round the  
restruction – in order to give different outputs, we must have  
different inputs, so lets think about a couple of ways of doing that:

Firstly, we can pass a 'seed' into our pure function with which to  
generate further random numbers.  Secondly, we can use Haskell's  
ability to deal with infinitely large data structures, and pass in an  
infinitely long list of 'random' numbers.  Here's the second one:

main = do
   seed <- do something to generate a seed
   interact $ pureMain . randoms $ seed

pureMain :: [Int] -> String -> String
pureMain rs "jam" = show (take 20 rs)

Hope that helps

Bob
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090128/96a913bb/attachment-0001.htm

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

Message: 5
Date: Wed, 28 Jan 2009 11:37:31 +0100
From: Heinrich Apfelmus <[email protected]>
Subject: [Haskell-beginners] Re: To use random number monad inside
        function
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Erick González wrote:
> Hi:
>
> Haskell' s way of random number generation is strange to me, but
> I know how to do that. I' d like to know how can I call random
> numbers generated on the screen inside a classic function. I mean, I
> need to know the way of calling random numbers (one different every
> time that I run) inside a function. Please, Could anybody help me? 
> Thanks

Section 3.1 of

    http://en.wikibooks.org/wiki/Haskell/Understanding_monads

explains how to work with random numbers in Haskell.


Regards,
apfelmus

-- 
http://apfelmus.nfshost.com



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

Message: 6
Date: Thu, 29 Jan 2009 12:18:23 +1100
From: Erik de Castro Lopo <[email protected]>
Subject: Re: [Haskell-beginners] Help! Trapped in the IO Monad!
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII

Alexander Dunlap wrote:

> You can do (something like; this is untested)
> 
> splitDirFile :: [FilePath] -> IO ([FilePath],[FilePath])
> splitDirFile [] = return ([],[])
> splitDirFile (f:fs) = do
>   (yess,nos) <- splitDirFile fs
>   exists <- doesDirectoryExist f
>   return $ if exists
>     then (f:yess,nos)
>     else (yess,f:nos)

Untested, but seems to work perfectly :-). Thanks.

However, that brings me to the next stage where again I'm trapped.
I would like to do a foldl' on a function that returns IO [FilePath].

I tried using Control.Monad.foldM, but then I end up with a function
taht return :

   IO (IO ([FilePath]))

which doesn't work :-).

It seems pretty obvious that I could implement a recursion like
Alexander did above for splitDirFile but I was wondering if there
was a more general solution.

Cheers,
Erik
-- 
-----------------------------------------------------------------
Erik de Castro Lopo
-----------------------------------------------------------------
Heisenbugs - The bugs that go away when you turn on debugging.


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

Message: 7
Date: Wed, 28 Jan 2009 17:30:00 -0800
From: Alexander Dunlap <[email protected]>
Subject: Re: [Haskell-beginners] Help! Trapped in the IO Monad!
To: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

On Wed, Jan 28, 2009 at 5:18 PM, Erik de Castro Lopo
<[email protected]> wrote:
> Alexander Dunlap wrote:
>
>> You can do (something like; this is untested)
>>
>> splitDirFile :: [FilePath] -> IO ([FilePath],[FilePath])
>> splitDirFile [] = return ([],[])
>> splitDirFile (f:fs) = do
>>   (yess,nos) <- splitDirFile fs
>>   exists <- doesDirectoryExist f
>>   return $ if exists
>>     then (f:yess,nos)
>>     else (yess,f:nos)
>
> Untested, but seems to work perfectly :-). Thanks.
>
> However, that brings me to the next stage where again I'm trapped.
> I would like to do a foldl' on a function that returns IO [FilePath].
>
> I tried using Control.Monad.foldM, but then I end up with a function
> taht return :
>
>   IO (IO ([FilePath]))
>
> which doesn't work :-).
>
> It seems pretty obvious that I could implement a recursion like
> Alexander did above for splitDirFile but I was wondering if there
> was a more general solution.
>
> Cheers,
> Erik

It seems like foldM ought to do what you want. Could you post some
more details please?

Alex


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

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


End of Beginners Digest, Vol 7, Issue 23
****************************************

Reply via email to