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
****************************************