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: Iterating through a list of char... (Stephen Tetley)
2. Re: Re: Iterating through a list of char... (Brent Yorgey)
3. Re: Re: Iterating through a list of char... (Stephen Tetley)
4. Re: Re: Iterating through a list of char... (Daniel Fischer)
5. Re: Iterating through a list of char... (Jean-Nicolas Jolivet)
6. Re: Re: Iterating through a list of char... (Ozgur Akgun)
----------------------------------------------------------------------
Message: 1
Date: Thu, 29 Apr 2010 18:40:56 +0100
From: Stephen Tetley <[email protected]>
Subject: Re: [Haskell-beginners] Re: Iterating through a list of
char...
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
On 29 April 2010 15:48, matthew coolbeth <[email protected]> wrote:
> I understand that higher-order functions are incredibly powerful, and that
> you can do essentially anything you might ever want while using only 'map'
> and 'foldl'.
Hello
In this case neither map nor foldl are adequate as both provide an
'elementary' consumption pattern i.e. one item is consumed at each
step.
mapAccumL can be seeded with a state tracking the previous element,
though as others have said you might want to define your own recursion
scheme:
replace2 :: (a -> a -> a) -> a -> [a] -> [a]
replace2 f2 initial xs = snd $ mapAccumL fn initial xs
where
fn a x = (x, f2 a x)
-- some example
replaceCharAfterA :: String -> String
replaceCharAfterA = replace2 fn 'Z' -- seed 'state' with 'Z' (wont match)
where
fn 'A' _ = '*'
fn _ b = b
demo1 = replaceCharAfterA "abcABC"
> demo1
"abcA*C"
Best wishes
Stephen
------------------------------
Message: 2
Date: Thu, 29 Apr 2010 14:00:47 -0400
From: Brent Yorgey <[email protected]>
Subject: Re: [Haskell-beginners] Re: Iterating through a list of
char...
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
On Thu, Apr 29, 2010 at 10:48:15AM -0400, matthew coolbeth wrote:
> I understand that higher-order functions are incredibly powerful, and that
> you can do essentially anything you might ever want while using only 'map'
> and 'foldl'.
>
> However, I have trouble believing that even experienced programmers wold
> find such HOF-oriented code to be more readable than Mr Akgun's solution:
>
> foo :: (a -> a -> a) -> [a] -> [a]
> foo f (x:y:rest) = f x y : foo f (y:rest)
> foo f _ = []
>
> It seems to me that 'foo', as defined here, is a direct restatement of the
> original program specification (the english one). Basically no translation
> required.
>
> If anyone here is enough of a veteran to prefer a map/fold implementation of
> this spec, I would be interested to hear about the thought processes you
> undertake when writing such code.
Instead of map/fold, I would absolutely prefer an implementation in
terms of zipWith:
> foo f xs = zipWith f xs (tail xs)
or perhaps
> foo f xs = zipWith f (i:xs) xs
where i is some sort of initial value. It is immediately clear to me
what this code does (match up "staggered" versions of xs, and zip
them up with the function f). On the other hand, the solution you
cited above takes me a a little time to read and digest, since it is
much more "low-level". Consider:
> foo :: (a -> a -> a) -> [a] -> [a]
> foo f (x:y:rest) = f x y : foo f (x:rest)
> foo f _ = []
This version is slightly (and crucially) different than the original.
Can you spot how? I can easily imagine typing this wrong version by
accident when trying to implement foo. And if it's that easy to make
a silly but dramatic change, it must take a correspondingly large
amount of energy to make sure you have understood all the details when
reading the code. On the other hand, I can't think of very many ways
to modify the zipWith implementation; there are far fewer pieces to
get right and/or understand.
Using higher-order functions and recursion combinators can be a
strange discipline at first, but with practice it frees you to forget
about details and think about things at a higher level.
-Brent
------------------------------
Message: 3
Date: Thu, 29 Apr 2010 19:01:14 +0100
From: Stephen Tetley <[email protected]>
Subject: Re: [Haskell-beginners] Re: Iterating through a list of
char...
To: Stephen Tetley <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Hello all
Correcting myself - in this case foldl is adequate - but it isn't
pleasant as the list is produced in the wrong order:
replaceCharAfterA_foldl' :: String -> String
replaceCharAfterA_foldl' xs = reverse $ snd $ foldl' f ('Z',[]) xs
where
f ('A',cca) b = (b,'*':cca)
f (_,cca) b = (b,b:cca)
demo2 = replaceCharAfterA_foldl' "abcABC"
> demo2
"abcA*C"
Best wishes
Stephen
------------------------------
Message: 4
Date: Thu, 29 Apr 2010 20:04:28 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Re: Iterating through a list of
char...
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"
Am Donnerstag 29 April 2010 16:48:15 schrieb matthew coolbeth:
> I understand that higher-order functions are incredibly powerful, and
> that you can do essentially anything you might ever want while using
> only 'map' and 'foldl'.
No, you absolutely need foldr 8)
(and foldl' is usually the better choice than foldl).
>
> However, I have trouble believing that even experienced programmers
> wold find such HOF-oriented code to be more readable than Mr Akgun's
> solution:
>
> foo :: (a -> a -> a) -> [a] -> [a]
> foo f (x:y:rest) = f x y : foo f (y:rest)
> foo f _ = []
>
> It seems to me that 'foo', as defined here, is a direct restatement of
> the original program specification (the english one). Basically no
> translation required.
foo f xs = zipWith f xs (drop 1 xs)
is equally readable - and that's it, I think; with experience, HOF-oriented
code becomes as readable as the direct recursive code.
>
> If anyone here is enough of a veteran to prefer a map/fold
> implementation of this spec, I would be interested to hear about the
> thought processes you undertake when writing such code.
No thought process, one just sees that it's a map/fold/... (after one has
spent enough time looking for folds and such). Often before one sees the
direct implementation.
Do I prefer a map/fold/scan/zipWith implementation of such a spec?
Yes and no.
There's one definite advantage to coding (and thinking) in higher order
functions/combinators. It helps identifying recurring patterns and then you
write the combinator for that pattern. Once. You need only prove the
correctness once. After that, you need only worry about the correctness of
the combining function.
>
> Thanks.
>
> On Thu, Apr 29, 2010 at 10:22, David Virebayre
> <[email protected]<dav.vire%[email protected]>
>
> > wrote:
> >
> > On Thu, Apr 29, 2010 at 3:52 PM, jean verdier <[email protected]>
> >
> > wrote:
> > > I may have missed it in this thread, but if not, why didn't anyone
> > > suggest:
> > >
> > > trans [] = []
> > > trans [x] = [x]
> > > trans ('a':_:xs) = 'a' : 'A' : trans xs
> > > trans (x:xs) = x : trans xs
> >
> > While as a beginner (I still am !) I would come up with a solution
> > like this one, on the long run it helps trying to solve those problem
> > with maps, folds, filters, and zips: Eventually, you'll find the code
> > more readable, easier to write, and there's perhaps a better chance
> > that it can be optimised by ghc.
> >
> > David.
------------------------------
Message: 5
Date: Thu, 29 Apr 2010 15:37:15 -0400
From: Jean-Nicolas Jolivet <[email protected]>
Subject: [Haskell-beginners] Re: Iterating through a list of char...
To: Jean-Nicolas Jolivet <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
First I would like to thank everyone for the very interesting replies and
suggestions I got so far!...
I tried to implement (and at the very least understand) most of them!...
To add to the context here, what I am trying to do is:
-apply a "transformation" to a character (in my case, subtracting 42 to its
ASCII value, which I obtain with chr(ord(c) - 42)
-if the character is preceded by a specific character (that would be, an escape
character, in this case '=') then subtract 106 to its value instead of 42...
-if the character is the escape character itself, '=', then skip it altogether
(keeping in mind that the next character needs to be escaped)...
I managed to do it, however I'm not totally satisfied in the way I did it...
the problem was that... as I just explained, in some cases, the character that
is being processed has to be "skipped" (and by that I mean, not added to the
resulting string). This happens when the processed character IS the escape
character...
What I did was to build a List of Maybe Char.... my function does the proper
operation on the character and returns a "Just Char" when the character is
processed, or Nothing when it is the escaped character... so basically I would
end up with something like: [Just 'f', Just 'o', Just 'o', Nothing]... I am
mapping this using mapMaybe to end up with a proper String...
Would there be any more efficient way of doing this? Considering that the
escape character should NOT be added to the resulting string, is there any way
I can avoid using the Maybe monad?
Once again, thanks everyone for all the suggestions!
Jean-Nicolas Jolivet
On 2010-04-28, at 10:56 AM, Jean-Nicolas Jolivet wrote:
> Hi there!
>
> I'm trying to iterate through each character of a string (that part I
> can do!) however, I need to apply a transformation to each
> character...based on the previous character in the string! This is the
> part I have no clue how to do!
>
> I'm totally new to Haskell so I'm pretty sure I'm missing something
> obvious... I tried with list comprehensions...map... etc... but I
> can't figure out how I can access the previous character in my string
> in each "iteration".... to use simple pseudo code, what i need to do
> is:
>
> while i < my_string length:
> if my_string[i-1] == some_char:
> do something with my_string[i]
> else
> do something else with my_string[i]
>
> I'm using imperative programming here obviously since it's what I am
> familiar with...but any help as to how I could "translate" this to
> functional programming would be really appreciated!
>
>
> Jean-Nicolas Jolivet
------------------------------
Message: 6
Date: Thu, 29 Apr 2010 21:26:50 +0100
From: Ozgur Akgun <[email protected]>
Subject: Re: [Haskell-beginners] Re: Iterating through a list of
char...
To: Jean-Nicolas Jolivet <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="utf-8"
I won't attempt writing a general-case function now. If I understood your
(rather long) description correctly, you want to
- subtract 42 from the ascii value of the char, except when it is preceeded
by '=', in which case you subtract 106 instead.
foo :: [Char] -> [Char]
foo ('=':x:xs) = chr (ord x - 106) : foo xs
foo (x:xs) = chr (ord x - 42) : foo xs
foo _ = []
Hope I understood the problem correctly.
Best,
On 29 April 2010 20:37, Jean-Nicolas Jolivet <[email protected]>wrote:
> First I would like to thank everyone for the very interesting replies and
> suggestions I got so far!...
>
> I tried to implement (and at the very least understand) most of them!...
>
> To add to the context here, what I am trying to do is:
>
> -apply a "transformation" to a character (in my case, subtracting 42 to its
> ASCII value, which I obtain with chr(ord(c) - 42)
> -if the character is preceded by a specific character (that would be, an
> escape character, in this case '=') then subtract 106 to its value instead
> of 42...
> -if the character is the escape character itself, '=', then skip it
> altogether (keeping in mind that the next character needs to be escaped)...
>
> I managed to do it, however I'm not totally satisfied in the way I did
> it... the problem was that... as I just explained, in some cases, the
> character that is being processed has to be "skipped" (and by that I mean,
> not added to the resulting string). This happens when the processed
> character IS the escape character...
>
> What I did was to build a List of Maybe Char.... my function does the
> proper operation on the character and returns a "Just Char" when the
> character is processed, or Nothing when it is the escaped character... so
> basically I would end up with something like: [Just 'f', Just 'o', Just
> 'o', Nothing]... I am mapping this using mapMaybe to end up with a proper
> String...
>
> Would there be any more efficient way of doing this? Considering that the
> escape character should NOT be added to the resulting string, is there any
> way I can avoid using the Maybe monad?
>
> Once again, thanks everyone for all the suggestions!
>
> Jean-Nicolas Jolivet
>
> On 2010-04-28, at 10:56 AM, Jean-Nicolas Jolivet wrote:
>
> > Hi there!
> >
> > I'm trying to iterate through each character of a string (that part I
> > can do!) however, I need to apply a transformation to each
> > character...based on the previous character in the string! This is the
> > part I have no clue how to do!
> >
> > I'm totally new to Haskell so I'm pretty sure I'm missing something
> > obvious... I tried with list comprehensions...map... etc... but I
> > can't figure out how I can access the previous character in my string
> > in each "iteration".... to use simple pseudo code, what i need to do
> > is:
> >
> > while i < my_string length:
> > if my_string[i-1] == some_char:
> > do something with my_string[i]
> > else
> > do something else with my_string[i]
> >
> > I'm using imperative programming here obviously since it's what I am
> > familiar with...but any help as to how I could "translate" this to
> > functional programming would be really appreciated!
> >
> >
> > Jean-Nicolas Jolivet
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
--
Ozgur Akgun
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20100429/a886dac6/attachment.html
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 22, Issue 46
*****************************************