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:  Questions on type declarations (ARJANEN Lo?c Jean David)
   2.  IO action on a list of [IO a] (Manfred Lotz)
   3. Re:  IO action on a list of [IO a] (koomi)
   4. Re:  IO action on a list of [IO a] (Henk-Jan van Tuyl)
   5. Re:  IO action on a list of [IO a] (Manfred Lotz)
   6. Re:  IO action on a list of [IO a] (Manfred Lotz)
   7. Re:  IO action on a list of [IO a] (Brent Yorgey)
   8. Re:  IO action on a list of [IO a] (ugo pozo)
   9.  Avoid Case Analyses (Costello, Roger L.)


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

Message: 1
Date: Sat, 06 Oct 2012 12:24:52 +0200
From: ARJANEN Lo?c Jean David <[email protected]>
Subject: Re: [Haskell-beginners] Questions on type declarations
To: [email protected]
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"; Format="flowed"

On 06/10/2012 02:06, brandon s allbery kf8nh wrote:
> On Friday, 5 October 2012 at 19:55, [email protected] wrote:
>> - getArgs :: IO [String]
>>
>> It can get several params, but its type declaration looks like it gets
>> none.
> It doesn't get any Haskell parameters; it retrieves OS-level (not 
> Haskell-level) parameters to the program.  If you know Perl, it's the 
> difference between @_ and @ARGV; if Python, the difference between 
> local parameters and sys.argv.  You might infer from the fact that 
> other languages also distinguish, that there is an actual difference 
> between function parameters and program parameters; if you are not 
> clear on this, you will need to figure it out regardless of the 
> language you're working with.
Perhaps the confusion comes from the fact that languages such as C or 
Java treat the program parameters as function arguments to main. 
Position which is not completely non-sensical when calls such as exec() 
exist, but I'd rather that they divide the OS-level arguments from the 
language-level ones: they are different after all.

And, judging from its signature, getArgs isn't a function without 
parameters but a value representing a list of program parameters, 
possibly empty. Said value coming from the system, it is in IO.
>> - dispatch :: [(String, [String] -> IO ())]
> Looks to me like it's described fairly well by the text.  What is your 
> confusion?
>
> It is an association list:  a list of pairs, the first element being a 
> key and the second being a value.  The value in this case is a 
> function which takes a list of strings and produces an IO action.
>
> -- 
> brandon s allbery kf8nh sine nomine associates
> [email protected]  [email protected]
> unix/linux, openafs, kerberos, infrastructure  http://sinenomine.net
>
> Sent with Sparrow <http://www.sparrowmailapp.com/?sig>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20121006/53cb456f/attachment-0001.htm>

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

Message: 2
Date: Sat, 6 Oct 2012 16:16:18 +0200
From: Manfred Lotz <[email protected]>
Subject: [Haskell-beginners] IO action on a list of [IO a]
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII

Hi all,
I want to do an IO action on a list of [IO a] like this:

myfor :: (a -> IO () ) -> [IO a] -> IO ()
myfor _ [] = return ()
myfor f (x:xs) = do 
  x' <- x
  f x'
  myfor f xs
    


Is there a library function doing just this?



-- 
Thanks,
Manfred





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

Message: 3
Date: Sat, 06 Oct 2012 16:56:36 +0200
From: koomi <[email protected]>
Subject: Re: [Haskell-beginners] IO action on a list of [IO a]
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

On 06.10.2012 16:16, Manfred Lotz wrote:
> Hi all,
> I want to do an IO action on a list of [IO a] like this:
>
> myfor :: (a -> IO () ) -> [IO a] -> IO ()
> myfor _ [] = return ()
> myfor f (x:xs) = do
>    x' <- x
>    f x'
>    myfor f xs
>      
>
>
> Is there a library function doing just this?
>
>
>
You could do: mapM_ (\x -> x >>= f) xs



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

Message: 4
Date: Sat, 06 Oct 2012 19:35:13 +0200
From: "Henk-Jan van Tuyl" <[email protected]>
Subject: Re: [Haskell-beginners] IO action on a list of [IO a]
To: [email protected], "Manfred Lotz" <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=iso-8859-15; format=flowed;
        delsp=yes

On Sat, 06 Oct 2012 16:16:18 +0200, Manfred Lotz <[email protected]>  
wrote:

> myfor :: (a -> IO () ) -> [IO a] -> IO ()
> myfor _ [] = return ()
> myfor f (x:xs) = do
>   x' <- x
>   f x'
>   myfor f xs
>
>
> Is there a library function doing just this?

You could use this:
   import Control.Monad
   myfor :: (a -> IO () ) -> [IO a] -> IO ()
   myfor f (x:xs) = mapM_ (liftM f) xs

or this:
   import Data.Functor
   myfor :: (a -> IO () ) -> [IO a] -> IO ()
   myfor f (x:xs) = mapM_ (f <$>) xs

For a description of liftM see:
   http://members.chello.nl/hjgtuyl/tourdemonad.html#liftM

Regards,
Henk-Jan van Tuyl


-- 
http://Van.Tuyl.eu/
http://members.chello.nl/hjgtuyl/tourdemonad.html
Haskell programming
--



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

Message: 5
Date: Sat, 6 Oct 2012 20:11:33 +0200
From: Manfred Lotz <[email protected]>
Subject: Re: [Haskell-beginners] IO action on a list of [IO a]
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII

On Sat, 06 Oct 2012 16:56:36 +0200
koomi <[email protected]> wrote:

> On 06.10.2012 16:16, Manfred Lotz wrote:
> > Hi all,
> > I want to do an IO action on a list of [IO a] like this:
> >
> > myfor :: (a -> IO () ) -> [IO a] -> IO ()
> > myfor _ [] = return ()
> > myfor f (x:xs) = do
> >    x' <- x
> >    f x'
> >    myfor f xs
> >      
> >
> >
> > Is there a library function doing just this?
> >
> >
> >
> You could do: mapM_ (\x -> x >>= f) xs
> 

Yep, that works nicely. Thanks.


-- 
Manfred





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

Message: 6
Date: Sat, 6 Oct 2012 20:38:18 +0200
From: Manfred Lotz <[email protected]>
Subject: Re: [Haskell-beginners] IO action on a list of [IO a]
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII

On Sat, 06 Oct 2012 19:35:13 +0200
"Henk-Jan van Tuyl" <[email protected]> wrote:

> On Sat, 06 Oct 2012 16:16:18 +0200, Manfred Lotz
> <[email protected]> wrote:
> 
> > myfor :: (a -> IO () ) -> [IO a] -> IO ()
> > myfor _ [] = return ()
> > myfor f (x:xs) = do
> >   x' <- x
> >   f x'
> >   myfor f xs
> >
> >
> > Is there a library function doing just this?
> 
> You could use this:
>    import Control.Monad
>    myfor :: (a -> IO () ) -> [IO a] -> IO ()
>    myfor f (x:xs) = mapM_ (liftM f) xs
> 
> or this:
>    import Data.Functor
>    myfor :: (a -> IO () ) -> [IO a] -> IO ()
>    myfor f (x:xs) = mapM_ (f <$>) xs
> 

Shouldn't it be xs instead of (x:xs)?

The signatures are the same as in my own myfor. However, when I run my
code using your versions of myfor I do not get any output at all.



-- 
Manfred
 

-- 
Manfred





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

Message: 7
Date: Sat, 6 Oct 2012 20:08:48 -0400
From: Brent Yorgey <[email protected]>
Subject: Re: [Haskell-beginners] IO action on a list of [IO a]
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

On Sat, Oct 06, 2012 at 07:35:13PM +0200, Henk-Jan van Tuyl wrote:
> On Sat, 06 Oct 2012 16:16:18 +0200, Manfred Lotz
> <[email protected]> wrote:
> 
> >myfor :: (a -> IO () ) -> [IO a] -> IO ()
> >myfor _ [] = return ()
> >myfor f (x:xs) = do
> >  x' <- x
> >  f x'
> >  myfor f xs
> >
> >
> >Is there a library function doing just this?
> 
> You could use this:
>   import Control.Monad
>   myfor :: (a -> IO () ) -> [IO a] -> IO ()
>   myfor f (x:xs) = mapM_ (liftM f) xs

This should be

  myfor f xs = mapM_ (>>= f) xs

using (liftM f) will result in the right type but it does the wrong
thing, as Manfred observed: 

  f :: a -> IO ()
  liftM f :: IO a -> IO (IO a)

So mapping liftM f over a list of IO actions results in a list of IO
actions with no effects, whose results are the IO actions you really
wanted.  Then mapM_ throws away those IO actions you really wanted,
resulting in essentially (return () :: IO ()).

-Brent



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

Message: 8
Date: Sat, 6 Oct 2012 21:49:53 -0300
From: ugo pozo <[email protected]>
Subject: Re: [Haskell-beginners] IO action on a list of [IO a]
To: Brent Yorgey <[email protected]>
Cc: [email protected]
Message-ID:
        <cajr8n44pweoonz-6xbaz_pyn4tg3jtwwjr31xybnkwlqan0...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

Here is my try. It works for any monad (not just IO) and any foldable
(not just lists).

import Data.Foldable

myfor :: (Monad m, Foldable t) => (a -> m ()) -> t (m a) -> m ()
myfor f = foldlM (flip $ const (>>=f)) ()

--
~ ugo pozo
~ mailto:[email protected]
~ home://11.3266.2021
~ cell://11.8432.9252


On Sat, Oct 6, 2012 at 9:08 PM, Brent Yorgey <[email protected]> wrote:
> On Sat, Oct 06, 2012 at 07:35:13PM +0200, Henk-Jan van Tuyl wrote:
>> On Sat, 06 Oct 2012 16:16:18 +0200, Manfred Lotz
>> <[email protected]> wrote:
>>
>> >myfor :: (a -> IO () ) -> [IO a] -> IO ()
>> >myfor _ [] = return ()
>> >myfor f (x:xs) = do
>> >  x' <- x
>> >  f x'
>> >  myfor f xs
>> >
>> >
>> >Is there a library function doing just this?
>>
>> You could use this:
>>   import Control.Monad
>>   myfor :: (a -> IO () ) -> [IO a] -> IO ()
>>   myfor f (x:xs) = mapM_ (liftM f) xs
>
> This should be
>
>   myfor f xs = mapM_ (>>= f) xs
>
> using (liftM f) will result in the right type but it does the wrong
> thing, as Manfred observed:
>
>   f :: a -> IO ()
>   liftM f :: IO a -> IO (IO a)
>
> So mapping liftM f over a list of IO actions results in a list of IO
> actions with no effects, whose results are the IO actions you really
> wanted.  Then mapM_ throws away those IO actions you really wanted,
> resulting in essentially (return () :: IO ()).
>
> -Brent
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners



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

Message: 9
Date: Sun, 7 Oct 2012 09:47:32 +0000
From: "Costello, Roger L." <[email protected]>
Subject: [Haskell-beginners] Avoid Case Analyses
To: "[email protected]" <[email protected]>
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="us-ascii"

Hi Folks,

"Programs that avoid case analyses are clearer and simpler than those that use 
case analyses."

Richard Bird made that surprising statement in his book, Introduction to 
Functional Programming using Haskell. 

It is worthwhile to understand why he said that. In the process we will see a 
fabulous example of how to start with a specification and systematically 
develop an implementation.

An extreme example of case analyses is using it to implement an identity 
function: 

color c         | c == "red"    = "red"
                | c == "green"          = "green"
                | c == "blue"   = "blue"

It is read:

- In the case the color c is "red" then return "red"
- In the case the color c is "green" then return "green" 
- In the case the color c is "blue" then return "blue"

The program is more clearly and simply implemented without case analyses:

        color c   =  c

Let's take a less trivial example. We will implement the floor function. 
Although Haskell already has a built-in floor function, it will be instructive 
to see how floor :: Float -> Integer can be programmed. The program will be 
developed in a systematic manner, starting with a specification for floor. 

After implementing  floor without case analyses, we will then compare it 
against an implementation that uses cases analyses. 

Recall that the floor of x is the largest integer n satisfying n <= x. Here are 
a couple examples:

        floor 2.3       returns 2
        floor (-2.3)    returns  -3

Let us begin with a specification of floor:

        floor                   ::     Float -> Integer
        floor x = n     ==   n <= x < n +1

floor maps a value of type Float to a value of type Integer. The floor of x is 
n, where x is between n and n +1.

It is tempting to plunge immediately into a case analysis, considering what to 
do if x is positive, what to do if x is negative, and, possibly, what to do if 
it is zero. But the specification does not mention cases and we should try not 
to mention cases either. 

How shall we find n, given an arbitrary x? 

You might respond: Simply truncate x's decimal point and its decimal digits, 
like so:

        truncate 2.3    returns 2

But that approach produces the wrong answer for negative values:

        truncate (-2.3)         returns (-2),  whereas the correct answer is -3

You might then suggest: If x is negative, then truncate and subtract 1.

But that is descending into a case analysis on the sign of x: if x is positive, 
then truncate; if x is negative, then truncate and subtract 1.

We do not need case analyses. The specification suggests an approach. 

The specification suggests that a search be conducted.

Search for an n that satisfies the condition n <= x, and then increase n until 
the condition x < n+1 holds:

- Start the search from some starting point, say, start n at 0.
- Lower n until n <= x
- Increase n until x < n+1

Example #1: find the floor of (-2.3):

- Start the search at n = 0
- Lower n until n <= x:  0, -1, -2, -3
- Increase n until x < n+1:  this terminates at once since -2.3 < (-3)+1

        floor (-2.3) is -3

Example #2: find the floor of 2.3:

- Start the search at n = 0
- Lower n until n <= x:  this terminates at once since 0 < 2.3
- Increase n until x < n+1:  0, 1, 2

        floor (2.3) is 2

The idea of searching until some condition holds can be encapsulated in a 
function until, defined by:

        until           ::  (a -> Bool) -> (a -> a) -> a -> a
        until p f x     =  if p x then x else until p f (f x)

Function until takes 3 arguments p, f, and x:

- p is a Boolean function. Function p is given a value x and it returns True or 
False. 

Example: this p returns True if x is less than zero (observe that p is a 
partially applied function):  

        p = (<0)

        p (-2)          returns True
        p 2             returns False

- f is a function that processes x.

Example: this f decreases x by one (observe that f is also a partially applied 
function):

        f = (subtract 1)

        f 5             returns 4
        f (-5)     returns (-6)

- x is the value operated on.

Read this use of function until:

        until (<0) (subtract 1) 5               returns  -1

like so: starting n at 5, repeatedly subtract 1 until n is less than 0.

Function until is a built-in Haskell function, as is floor, but for learning 
purposes we will use our own implementation of them, so place this at the top 
of your file to hide the built-in version:

        import Prelude hiding (until, floor)

To search for an n satisfying the condition n <= x we will use this function 
lower:

        x = (-2.3)

        lower  =  until (<=x) decrease 
                           where decrease n  =  n - 1

Function lower decreases its argument n until the condition n <= x is satisfied:

        lower 5         returns  -3
        lower (-5)      returns  -5

Suppose we wish to find the floor of (5.3) and we start our search at n = 0. 
Function lower immediately returns because the condition 0 <= 5.3 is 
immediately satisfied:

        x = 5.3
        lower 0         returns 0

In this example, the result n found by the search is too small. We need a 
second search to increase n until the condition x < n+1 is satisfied. We will 
increase n in steps of 1 to ensure the condition n <= x is maintained. 
Actually, we will increase n until it just exceeds x and then decrease it by 1. 
We create a function upper for this:

        upper  =  until (>x) increase
                               where increase n  =  n + 1

        decrease n = n - 1

The output of function upper will be the input to function decrease, so we 
compose the two functions:

        decrease . upper

Further, we want the input of (decrease . upper) to be the output of function 
lower, so we compose them:

        decrease . upper . lower

Example: we wish to find the floor of (5.3) and we start our search at n=0. 
Function lower immediately returns 0 because the condition 0 <= 5.3 is 
satisfied. Function upper increases 0 to 6, at which point 6 > 5.3 is 
satisfied. Finally, 6 is decreased by 1 to the answer 5:

        x = 5.3
        (decrease . upper . lower) 0    returns 5

We now have all the ingredients needed to create function floor. The function 
takes one argument, x:

        floor x

It starts the search from some point, let's choose n=0 as the starting point:

        floor x  =  searchFrom 0

Function searchFrom lowers n=0 until the condition n <= x is satisfied and then 
raises n until the condition n > x is satisfied and then decreases n by 1: 

        floor x  =  searchFrom 0
                   where  searchFrom  =  decrease . upper . lower

Add the definitions for decrease, upper, and lower:

        floor x  =  searchFrom 0
                where   searchFrom      =  decrease . upper . lower
                                lower                   =  until (<=x) decrease
                                upper                   =  until (>x) increase
                                decrease n      =  n - 1
                                increase n      =  n + 1

Notice that this implementation of function floor does not use case analyses. 
The program is surprisingly short, owing mainly to the absence of a case 
analysis on the sign of x.

Compare that with a version that uses case analyses: 

floor x         | x < 0         =  lower 0
                | x > 0         =  (decrease . upper) 0
                | x == 0        =  0
               where  lower             =  until (<=x) decrease
                            upper               =  until (>x) increase
                            decrease n  =  n - 1
                            increase n  =  n + 1

Read as: if x is less than 0 then lower 0 until n <= x is satisfied. If x is 
greater than 0 then increase 0 until n > x is satisfied and then decrease n by 
1. Lastly, if x equals 0 then return 0.

The case analysis version is longer and arguably more complex.

/Roger



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

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


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

Reply via email to