Re: [Haskell-cafe] Problems interpreting

On Mon, Sep 18, 2006 at 12:54:34PM +0200, Albert Crespi wrote:
Thank you very much for your reply! As I said, it is my first experience with Haskell, I have been programming in Java and C for some years, and I find this language very different from them. Anyway I'll try to fix the function with the information that you gave me. Thanks again!
You're welcome. By the way, this is what the comments say you are trying to do: -- Replaces a wildcard in a list with the list given as the third argument substitute :: Eq a => a -> [a] -> [a] -> [a] substitute e l1 l2= [c | c <- check_elem l1] where check_elem [] = l1 check_elem (x:xs) = if x == e then (l2 ++ xs) else check_elem xs This is the result: *Main> substitute 1 [1,2,3] [] [2,3] *Main> substitute 1 [1,2,3] [7,8,9] [7,8,9,2,3] *Main> Have fun with Haskell. Ciao Andrea

Wow! I'm starting to love this languaje, and the people who uses it!:) Andrea Rossato wrote:
On Mon, Sep 18, 2006 at 12:54:34PM +0200, Albert Crespi wrote:
Thank you very much for your reply! As I said, it is my first experience with Haskell, I have been programming in Java and C for some years, and I find this language very different from them. Anyway I'll try to fix the function with the information that you gave me. Thanks again!
You're welcome.
By the way, this is what the comments say you are trying to do:
-- Replaces a wildcard in a list with the list given as the third argument substitute :: Eq a => a -> [a] -> [a] -> [a] substitute e l1 l2= [c | c <- check_elem l1] where check_elem [] = l1 check_elem (x:xs) = if x == e then (l2 ++ xs) else check_elem xs
This is the result:
*Main> substitute 1 [1,2,3] [] [2,3] *Main> substitute 1 [1,2,3] [7,8,9] [7,8,9,2,3] *Main>
Have fun with Haskell.
Ciao Andrea _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://www.nabble.com/Problems-interpreting-tf2290155.html#a6361815 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

On Mon, Sep 18, 2006 at 04:16:55AM -0700, Carajillu wrote:
Wow! I'm starting to love this languaje, and the people who uses it!:)
You spoke too early. My code had a bug, a huge one... this is the right one: -- Replaces a wildcard in a list with the list given as the third argument substitute :: Eq a => a -> [a] -> [a] -> [a] substitute e l1 l2= [c | c <- check_elem l1] where check_elem [] = l1 check_elem (x:xs) = if x == e then (l2 ++ xs) else [x] ++ check_elem xs Ciao, Andrea

Finally I took Andrea's solution "check_elem (x:xs) = if x == e then (l2 ++ xs) else [x] ++ check_elem xs" I think it's easy to understand for me ( in my noob level), than the recursive one. I'm testing it and it's working really well. The other solutions are a little complicated for me, but I'm still trying to undestand them. Thanks! Andrea Rossato wrote:
On Mon, Sep 18, 2006 at 12:25:21PM +0100, Neil Mitchell wrote:
Why not:
check_elem (x:xs) = if x == e then (l2 ++ xs) else x : check_elem xs
Thanks
Thank you! Lists are my personal nightmare...;-)
Andrea _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://www.nabble.com/Problems-interpreting-tf2290155.html#a6362822 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Not a good solution, it just substitutes the first occurrence of the item in the list. I'll try the others Carajillu wrote:
Finally I took Andrea's solution "check_elem (x:xs) = if x == e then (l2 ++ xs) else [x] ++ check_elem xs" I think it's easy to understand for me ( in my noob level), than the recursive one. I'm testing it and it's working really well. The other solutions are a little complicated for me, but I'm still trying to undestand them. Thanks!
Andrea Rossato wrote:
On Mon, Sep 18, 2006 at 12:25:21PM +0100, Neil Mitchell wrote:
Why not:
check_elem (x:xs) = if x == e then (l2 ++ xs) else x : check_elem xs
Thanks
Thank you! Lists are my personal nightmare...;-)
Andrea _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://www.nabble.com/Problems-interpreting-tf2290155.html#a6362912 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

On Mon, Sep 18, 2006 at 02:52:45PM +0200, Andrea Rossato wrote:
On Mon, Sep 18, 2006 at 05:42:47AM -0700, Carajillu wrote:
Not a good solution, it just substitutes the first occurrence of the item in the list. I'll try the others
I did not get this point. You must take Jón's approach with map.
or use this line in mine: check_elem (x:xs) = if x == e then l2 ++ check_elem xs else x : check_elem xs that is to say, you must check also the tail after the matched element. andrea

On Mon, Sep 18, 2006 at 05:35:47AM -0700, Carajillu wrote:
I'm testing it and it's working really well. The other solutions are a little complicated for me, but I'm still trying to undestand them.
Jón's approach (the last version of his message), usually cleaner and more concise, is called point-free and is quite common in functional programming. It can be a bit confusing to newcomers, though, since part of the function's arguments do not appear explicitly in the expressions' body (as the list to be matched and modified in your example). You can read something more about this style here: http://haskell.org/haskellwiki/Pointfree Hope this helps. Andrea

Andrea Rossato
On Mon, Sep 18, 2006 at 04:16:55AM -0700, Carajillu wrote:
Wow! I'm starting to love this languaje, and the people who uses it!:)
You spoke too early. My code had a bug, a huge one...
this is the right one:
-- Replaces a wildcard in a list with the list given as the third argument substitute :: Eq a => a -> [a] -> [a] -> [a] substitute e l1 l2= [c | c <- check_elem l1] where check_elem [] = l1 check_elem (x:xs) = if x == e then (l2 ++ xs) else [x] ++ check_elem xs
I think it's nicer to do it like this: substitute e l l' = concat (map subst_elem l) where subst_elem x | x == e = l' | otherwise = [x] since "subst_elem" has a more straightforward meaning than "check_elem", and the concatenation is handled by a well known standard function. Also, it would usually be more useful to have the argument to replace /with/ before the argument to replace /in/, so that ("substitute '*' "wurble") is a function that replaces all the '*'s in it's argument with "wurble"s. And if you do that, you can write it like this: subst e l' = concat . map subst_elem where subst_elem x | x == e = l' | otherwise = [x] -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

On Mon, Sep 18, 2006 at 12:42:59PM +0100, Jón Fairbairn wrote:
And if you do that, you can write it like this:
subst e l' = concat . map subst_elem where subst_elem x | x == e = l' | otherwise = [x]
Pretty. Just to many keystrokes. This should take two keystrokes less, probably: subst e l [] = [] subst e l (x:xs) = if x == e then l ++ xs else x : subst e l xs ;-) andrea

Hello Andrea, Monday, September 18, 2006, 4:23:21 PM, you wrote:
subst e l' = concat . map subst_elem where subst_elem x | x == e = l' | otherwise = [x]
Pretty. Just to many keystrokes. This should take two keystrokes less, probably:
subst e l [] = [] subst e l (x:xs) = if x == e then l ++ xs else x : subst e l xs
but the goal is not keystrokes itself but easy of understanding. for me, first solution looks rather idiomatic and "intuitively" understandable. second solution requires more time to "got it", but seems easier for novices that are not yet captured higher-level Haskell idioms. i just want to said that it will be easier to read it if you split it into several lines: subst e l [] = [] subst e l (x:xs) = if x == e then l ++ xs else x : subst e l xs or subst e l [] = [] subst e l (x:xs) | x==e = l ++ xs | otherwise = x : subst e l xs and that your solution substitutes only first match in a list: subst 1 [1,1] [0] = [0,1] -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Mon, Sep 18, 2006 at 04:52:33PM +0400, Bulat Ziganshin wrote:
but the goal is not keystrokes itself but easy of understanding. for me, first solution looks rather idiomatic and "intuitively" understandable. second solution requires more time to "got it", but seems easier for novices that are not yet captured higher-level Haskell idioms.
I was obviously kidding, as the ";-)" should have made clear. ;-) Apart for the bug (I did not understand that all the occurrences should be replaced) I wrote something that was as close as possible to Albert's first attempt. For the rest, I completely agree with you and find the second one a lot easier... Andrea

Andrea Rossato
On Mon, Sep 18, 2006 at 12:42:59PM +0100, Jón Fairbairn wrote:
And if you do that, you can write it like this:
subst e l' = concat . map subst_elem where subst_elem x | x == e = l' | otherwise = [x]
Pretty. Just to many keystrokes.
Keystrokes? Learn to touchtype!
This should take two keystrokes less, probably:
subst e l [] = [] subst e l (x:xs) = if x == e then l ++ xs else x : subst e l xs
but if you want short, do this:
subst e l' = concat.map (\x->if x==e then l' else [x])
which beats yours by twenty seven characters and one bug ;-P -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html (updated 2006-09-13)

Hi, Am Montag, den 18.09.2006, 16:00 +0100 schrieb Neil Mitchell:
subst e l' = concat.map (\x->if x==e then l' else [x]) subst e l' = concatMap (\x->if x==e then l' else [x]) Let's save an extra character :) We are talking keystrokes here, so count the shift key!
Greetings, Joachim -- Joachim Breitner e-Mail: mail@joachim-breitner.de Homepage: http://www.joachim-breitner.de ICQ#: 74513189

Hi,
On 9/18/06, Joachim Breitner
Hi,
Am Montag, den 18.09.2006, 16:00 +0100 schrieb Neil Mitchell:
subst e l' = concat.map (\x->if x==e then l' else [x]) subst e l' = concatMap (\x->if x==e then l' else [x]) Let's save an extra character :) We are talking keystrokes here, so count the shift key!
Greetings, Joachim
Sorry, couldn't resist... If we *really* talking keystrokes, it much depends on auto-completion features of your editor! :) V.Rudenko -- λ is the ultimate

Hi, Out of curiosity, I've been developing a tool called Dr Haskell, for a sample run: -------------------------------- module Test where substitute1 :: Eq a => a -> [a] -> [a] -> [a] substitute1 e l1 l2= [c | c <- check_elem l1] where check_elem [] = l1 check_elem (x:xs) = if x == e then (l2 ++ xs) else [x] ++ check_elem xs substitute2 e l l' = concat (map subst_elem l) where subst_elem x | x == e = l' | otherwise = [x] subst3 e l [] = [] subst3 e l (x:xs) = if x == e then l ++ xs else x : subst3 e l xs subst4 e l' = concat.map (\x->if x==e then l' else [x]) ----------------------------
drhaskell Test.hs
I can apply Hints.concat_map in Test.subst4
I can apply Hints.concat_map in Test.substitute2
I can apply Hints.box_append in Test.Test.Prelude.200.check_elem
For the curious, see the darcs repo:
http://www.cs.york.ac.uk/fp/darcs/drhaskell/
(Requires Yhc)
Thanks
Neil
PS. dons also contributed some of the earlier discussion to this tool,
so deserves some credit.
On 9/18/06, wld
Hi, On 9/18/06, Joachim Breitner
wrote: Hi,
Am Montag, den 18.09.2006, 16:00 +0100 schrieb Neil Mitchell:
subst e l' = concat.map (\x->if x==e then l' else [x]) subst e l' = concatMap (\x->if x==e then l' else [x]) Let's save an extra character :) We are talking keystrokes here, so count the shift key!
Greetings, Joachim
Sorry, couldn't resist... If we *really* talking keystrokes, it much depends on auto-completion features of your editor! :)
V.Rudenko -- λ is the ultimate
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Or even shorter: subst e l = concatMap $ \x->if x==e then l else [x] I kinda like the list comprehension version too subst e l1 l2 = [ r | x <- l2, r <- if x==e then l1 else [x] ] On Sep 18, 2006, at 10:54 , Jón Fairbairn wrote:
Andrea Rossato
writes: On Mon, Sep 18, 2006 at 12:42:59PM +0100, Jón Fairbairn wrote:
And if you do that, you can write it like this:
subst e l' = concat . map subst_elem where subst_elem x | x == e = l' | otherwise = [x]
Pretty. Just to many keystrokes.
Keystrokes? Learn to touchtype!
This should take two keystrokes less, probably:
subst e l [] = [] subst e l (x:xs) = if x == e then l ++ xs else x : subst e l xs
but if you want short, do this:
subst e l' = concat.map (\x->if x==e then l' else [x])
which beats yours by twenty seven characters and one bug ;-P
-- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html (updated 2006-09-13)
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Mon, Sep 18, 2006 at 11:04:27AM -0400, Lennart Augustsson wrote:
Or even shorter:
subst e l = concatMap $ \x->if x==e then l else [x]
I kinda like the list comprehension version too
subst e l1 l2 = [ r | x <- l2, r <- if x==e then l1 else [x] ]
This is the version I first wanted to (try to) implement (improvements thanks to the thread, obviously :-): newtype SF a b = SF { runSF :: [a] -> [b] } instance Arrow SF where arr f = SF (map f) SF f >>> SF g = SF (f >>> g) first (SF f) = SF (unzip >>> first f >>> uncurry zip) substitute e l = arr (\x->if x==e then l else [x]) >>> SF concat I was studying Hughes when I read the first mail of this thread. But you can see it yourself... Andrea

On 2006-09-18, Jón Fairbairn
Andrea Rossato
writes: On Mon, Sep 18, 2006 at 12:42:59PM +0100, Jón Fairbairn wrote:
And if you do that, you can write it like this:
subst e l' = concat . map subst_elem where subst_elem x | x == e = l' | otherwise = [x]
Pretty. Just to many keystrokes.
Keystrokes? Learn to touchtype!
One has only a finite number of keystrokes before one's hands give out. Use them wisely. -- Aaron Denney -><-

On 18/09/06, Aaron Denney
One has only a finite number of keystrokes before one's hands give out. Use them wisely.
i agr rdndncy = bd & shd b stmpd out wsts bndwth 2 Slightly more seriously, a few extra keystrokes can -really- improve clarity. For example, you can write English and still be understood (reasonably) well without most of the vowels. But how on Earth do you interpret "ld mn gd t shp"? Or any Perl/Ruby/whatever golf entry? I'd rather waste keystrokes writing clearer code than brain cycles understanding obfuscated code, personally. --Sam

Definitely I'll take this solution, I'm reading about Pointfree, I think it's not that dificult to understand. And moreover it's the simpliest way to write code. Jón Fairbairn-2 wrote:
Andrea Rossato
writes: On Mon, Sep 18, 2006 at 04:16:55AM -0700, Carajillu wrote:
Wow! I'm starting to love this languaje, and the people who uses it!:)
You spoke too early. My code had a bug, a huge one...
this is the right one:
-- Replaces a wildcard in a list with the list given as the third argument substitute :: Eq a => a -> [a] -> [a] -> [a] substitute e l1 l2= [c | c <- check_elem l1] where check_elem [] = l1 check_elem (x:xs) = if x == e then (l2 ++ xs) else [x] ++ check_elem xs
I think it's nicer to do it like this:
substitute e l l' = concat (map subst_elem l) where subst_elem x | x == e = l' | otherwise = [x]
since "subst_elem" has a more straightforward meaning than "check_elem", and the concatenation is handled by a well known standard function.
Also, it would usually be more useful to have the argument to replace /with/ before the argument to replace /in/, so that ("substitute '*' "wurble") is a function that replaces all the '*'s in it's argument with "wurble"s.
And if you do that, you can write it like this:
subst e l' = concat . map subst_elem where subst_elem x | x == e = l' | otherwise = [x]
-- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://www.nabble.com/Problems-interpreting-tf2290155.html#a6363827 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Hello Andrea, Monday, September 18, 2006, 3:22:43 PM, you wrote:
substitute e l1 l2= [c | c <- check_elem l1]
why not just substitute e l1 l2= check_elem l1 ? :)
where check_elem [] = l1
should be where check_elem [] = [] otherwise you just append second (backup? :) copy of original list to result :) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
participants (10)
-
Aaron Denney
-
Andrea Rossato
-
Bulat Ziganshin
-
Carajillu
-
Joachim Breitner
-
Jón Fairbairn
-
Lennart Augustsson
-
Neil Mitchell
-
Sam Pointon
-
wld