John | 14 May 16:57 2013
Picon

list comprehension doesn't work

Hi,

I have to write a function which returns a list of all pairs (x,y) where x,
y ∈ N AND:
–  x is the product of two natural numbers (x = a · b, where a, b ∈ N) AND
–  x is really bigger than 5 but really smaller than 500, AND
–  y is a squer number (y = c² where c ∈ N) NOT greater than 1000, AND
–  x is a divisor of y.

My attempt is as follows:

listPairs :: [(Int, Int)]
listPairs = [(x,y) | x<-[0..], y<-[0..], x<-[0..]*[0..], x > 5, x < 500,
(y*y) < 1001, mod y x == 0]

However it doesn't work unfortunatly 

Could anyone tell me where my mistake is?

Thanks.

--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
(Continue reading)

Alejandro Serrano Mena | 14 May 17:03 2013
Picon

Re: list comprehension doesn't work

For a first sight, you cannot use x <- [0..]*[0..] to mean 'all possible pairs x = a*b'.
You would need to do something like
[ (a*b, y) | a <- [0..], b <- [0..], a*b > 5, a*b < 500, and the rest of things ]


2013/5/14 John <knowledge1202 <at> gmail.com>
Hi,

I have to write a function which returns a list of all pairs (x,y) where x,
y ∈ N AND:
–  x is the product of two natural numbers (x = a · b, where a, b ∈ N) AND
–  x is really bigger than 5 but really smaller than 500, AND
–  y is a squer number (y = c² where c ∈ N) NOT greater than 1000, AND
–  x is a divisor of y.

My attempt is as follows:

listPairs :: [(Int, Int)]
listPairs = [(x,y) | x<-[0..], y<-[0..], x<-[0..]*[0..], x > 5, x < 500,
(y*y) < 1001, mod y x == 0]

However it doesn't work unfortunatly

Could anyone tell me where my mistake is?

Thanks.



--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
John | 14 May 17:17 2013
Picon

Re: list comprehension doesn't work

thanks to both!

listPairs = [(a*b, y) | a <- [0..], b <- [0..], (a*b) > 5, (a*b) < 500,
(y*y) < 1001, mod y x == 0]

Now I have it as you said, however the compiler complains about all y and x
and says they are NOT in scope.

Why is it so? I can't see any problem with that...

--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158p5730161.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
Danny Gratzer | 14 May 17:20 2013
Picon

Re: list comprehension doesn't work

Well you've deleted the portion of the code referring to x and y.

listPairs = [(a*b, y) | y <- [0..], a <- [0..], b <- [0..], (a*b) > 5, (a*b) < 500, (y*y) < 1001, mod y (a*b) == 0]

This will still never terminate however.


On Tue, May 14, 2013 at 10:17 AM, John <knowledge1202 <at> gmail.com> wrote:
thanks to both!

listPairs = [(a*b, y) | a <- [0..], b <- [0..], (a*b) > 5, (a*b) < 500,
(y*y) < 1001, mod y x == 0]

Now I have it as you said, however the compiler complains about all y and x
and says they are NOT in scope.

Why is it so? I can't see any problem with that...




--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158p5730161.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



--
Danny Gratzer
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Brandon Allbery | 14 May 17:22 2013
Picon

Re: list comprehension doesn't work

On Tue, May 14, 2013 at 11:17 AM, John <knowledge1202 <at> gmail.com> wrote:
listPairs = [(a*b, y) | a <- [0..], b <- [0..], (a*b) > 5, (a*b) < 500,
(y*y) < 1001, mod y x == 0]

Now I have it as you said, however the compiler complains about all y and x
and says they are NOT in scope.

Why is it so? I can't see any problem with that...

I don't see any definitions of x or y there. (Note that you have replaced x with a*b.)

--
brandon s allbery kf8nh                               sine nomine associates
allbery.b <at> gmail.com                                  ballbery <at> sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Danny Gratzer | 14 May 17:05 2013
Picon

Re: list comprehension doesn't work

You can't write 

    [1..] * [1..]

Since Haskell's lists aren't Nums

Instead you'd want to write something like

a<-[1..], b<-[1..], and then multiply them together manually.

But this still doesn't really work since it'll loop forever without finding any solutions. Haskell's list comprehensions don't play very nicely with multiple infinite lists. If you really want to use this style of programming for your problem, have a look at the logict package on Hackage, it has functions designed to solve the problem of multiple infinite choices.


On Tue, May 14, 2013 at 9:57 AM, John <knowledge1202 <at> gmail.com> wrote:
Hi,

I have to write a function which returns a list of all pairs (x,y) where x,
y ∈ N AND:
–  x is the product of two natural numbers (x = a · b, where a, b ∈ N) AND
–  x is really bigger than 5 but really smaller than 500, AND
–  y is a squer number (y = c² where c ∈ N) NOT greater than 1000, AND
–  x is a divisor of y.

My attempt is as follows:

listPairs :: [(Int, Int)]
listPairs = [(x,y) | x<-[0..], y<-[0..], x<-[0..]*[0..], x > 5, x < 500,
(y*y) < 1001, mod y x == 0]

However it doesn't work unfortunatly

Could anyone tell me where my mistake is?

Thanks.



--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



--
Danny Gratzer
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Keshav Kini | 16 May 04:26 2013
Picon

Re: list comprehension doesn't work

Danny Gratzer <danny.gratzer <at> gmail.com> writes:
> But this still doesn't really work since it'll loop forever without
> finding any solutions. Haskell's list comprehensions don't play very
> nicely with multiple infinite lists. If you really want to use this
> style of programming for your problem, have a look at the logict
> package on Hackage, it has functions designed to solve the problem of
> multiple infinite choices.

See also the control-monad-omega package.

-Keshav

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Daniel Díaz Casanueva | 14 May 17:22 2013
Picon

Re: list comprehension doesn't work

You can always write it like this:

listPairs = [ (x,y) | x <- [6 .. 499] ,  y <- [0 .. 1000] , isProduct x , isSqrt y , mod y x == 0 ]

So you have the bounds for x and y, and then the conditions. You then need to define isProduct and isSqrt with types

isProduct :: Int -> Bool
isSqrt :: Int -> Bool

Hopefully, these problems will look easier separately.

Well, it's just an idea.

Good luck,
Daniel Díaz.


On Tue, May 14, 2013 at 4:57 PM, John <knowledge1202 <at> gmail.com> wrote:
Hi,

I have to write a function which returns a list of all pairs (x,y) where x,
y ∈ N AND:
–  x is the product of two natural numbers (x = a · b, where a, b ∈ N) AND
–  x is really bigger than 5 but really smaller than 500, AND
–  y is a squer number (y = c² where c ∈ N) NOT greater than 1000, AND
–  x is a divisor of y.

My attempt is as follows:

listPairs :: [(Int, Int)]
listPairs = [(x,y) | x<-[0..], y<-[0..], x<-[0..]*[0..], x > 5, x < 500,
(y*y) < 1001, mod y x == 0]

However it doesn't work unfortunatly

Could anyone tell me where my mistake is?

Thanks.



--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



--
E-mail sent by Daniel Díaz Casanueva

let f x = x in x
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Daniel Díaz Casanueva | 14 May 17:24 2013
Picon

Re: list comprehension doesn't work

Well, definitely, isSqrt should be called isSquare.


On Tue, May 14, 2013 at 5:22 PM, Daniel Díaz Casanueva <dhelta.diaz <at> gmail.com> wrote:
You can always write it like this:

listPairs = [ (x,y) | x <- [6 .. 499] ,  y <- [0 .. 1000] , isProduct x , isSqrt y , mod y x == 0 ]

So you have the bounds for x and y, and then the conditions. You then need to define isProduct and isSqrt with types

isProduct :: Int -> Bool
isSqrt :: Int -> Bool

Hopefully, these problems will look easier separately.

Well, it's just an idea.

Good luck,
Daniel Díaz.


On Tue, May 14, 2013 at 4:57 PM, John <knowledge1202 <at> gmail.com> wrote:
Hi,

I have to write a function which returns a list of all pairs (x,y) where x,
y ∈ N AND:
–  x is the product of two natural numbers (x = a · b, where a, b ∈ N) AND
–  x is really bigger than 5 but really smaller than 500, AND
–  y is a squer number (y = c² where c ∈ N) NOT greater than 1000, AND
–  x is a divisor of y.

My attempt is as follows:

listPairs :: [(Int, Int)]
listPairs = [(x,y) | x<-[0..], y<-[0..], x<-[0..]*[0..], x > 5, x < 500,
(y*y) < 1001, mod y x == 0]

However it doesn't work unfortunatly

Could anyone tell me where my mistake is?

Thanks.



--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



--
E-mail sent by Daniel Díaz Casanueva

let f x = x in x



--
E-mail sent by Daniel Díaz Casanueva

let f x = x in x
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Danny Gratzer | 14 May 17:29 2013
Picon

Re: list comprehension doesn't work

Isn't the product check actually redundant? re-reading the requirements we could just define a = 1 and b = x. Maybe I'm misunderstanding though.


On Tue, May 14, 2013 at 10:24 AM, Daniel Díaz Casanueva <dhelta.diaz <at> gmail.com> wrote:
Well, definitely, isSqrt should be called isSquare.


On Tue, May 14, 2013 at 5:22 PM, Daniel Díaz Casanueva <dhelta.diaz <at> gmail.com> wrote:
You can always write it like this:

listPairs = [ (x,y) | x <- [6 .. 499] ,  y <- [0 .. 1000] , isProduct x , isSqrt y , mod y x == 0 ]

So you have the bounds for x and y, and then the conditions. You then need to define isProduct and isSqrt with types

isProduct :: Int -> Bool
isSqrt :: Int -> Bool

Hopefully, these problems will look easier separately.

Well, it's just an idea.

Good luck,
Daniel Díaz.


On Tue, May 14, 2013 at 4:57 PM, John <knowledge1202 <at> gmail.com> wrote:
Hi,

I have to write a function which returns a list of all pairs (x,y) where x,
y ∈ N AND:
–  x is the product of two natural numbers (x = a · b, where a, b ∈ N) AND
–  x is really bigger than 5 but really smaller than 500, AND
–  y is a squer number (y = c² where c ∈ N) NOT greater than 1000, AND
–  x is a divisor of y.

My attempt is as follows:

listPairs :: [(Int, Int)]
listPairs = [(x,y) | x<-[0..], y<-[0..], x<-[0..]*[0..], x > 5, x < 500,
(y*y) < 1001, mod y x == 0]

However it doesn't work unfortunatly

Could anyone tell me where my mistake is?

Thanks.



--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



--
E-mail sent by Daniel Díaz Casanueva

let f x = x in x



--
E-mail sent by Daniel Díaz Casanueva

let f x = x in x

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe




--
Danny Gratzer
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
John | 14 May 17:41 2013
Picon

Re: list comprehension doesn't work

Danny Gratzer wrote
> Well you've deleted the portion of the code referring to x and y.
> 
> listPairs = [(a*b, y) | y <- [0..], a <- [0..], b <- [0..], (a*b) > 5,
> (a*b) < 500, (y*y) < 1001, mod y (a*b) == 0]
> 
> This will still never terminate however.

oh I see, but as you say it doesn't terminate and I get nothing. Does it
mean, that the function is wrong in this place?

Some questions:
1. Does the order of conditions affect the result at all?
2. The "," means AND or &&, right? So how do you write OR || instead? E.g
z<-[1..10] OR z<-[100..110].
Ofcourse it doesn't relate to this topic, but I wanted to know it.

Since I'm a very beginner I think the approach of Daniel is slightly complex
for me to comprehend, right?
Allthough I tried it, but it says isProduct and isSquer are not in Scope, so
I should define them first in WHERE-Clause right?

Thanks again to all

--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158p5730167.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
John | 14 May 17:47 2013
Picon

Re: list comprehension doesn't work

Danny Gratzer wrote
> Isn't the product check actually redundant? re-reading the requirements we
> could just define a = 1 and b = x. Maybe I'm misunderstanding though.

I'm not sure. As I understand the requirement, the squer of y should not be
greater than 1000.

But anyway, without this condition it doesn't work yet 

Do you have any idea, what is wrong with it now?

--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158p5730168.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
Danny Gratzer | 14 May 17:48 2013
Picon

Re: list comprehension doesn't work


1. Does the order of conditions affect the result at all?

Conditions, I don't believe so, the ordering/placement of bindings though can effect the results a great deal.

When I say bindings, I mean something that involves a <-
 
2. The "," means AND or &&, right? So how do you write OR || instead? E.g
z<-[1..10] OR z<-[100..110].

For that scenario I'd just append the lists, z <- [1..10]++[100..110], if you wanted an or in conditions, you'd just use ||

 
Allthough I tried it, but it says isProduct and isSquer are not in Scope, so
I should define them first in WHERE-Clause right?

Yep, eg

listPairs = [...]
  where isSquare = ...
           isProduct = ... 
--
Danny Gratzer
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
John | 14 May 17:59 2013
Picon

Re: list comprehension doesn't work

is'nt it possible, to write it in one line without any nested functions in
WHERE?
If it's possible I'd prefer that...

any idea?

Thanks

--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158p5730170.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
Mateusz Kowalczyk | 14 May 18:43 2013
Picon

Re: list comprehension doesn't work


On 14/05/13 16:59, John wrote:
> is'nt it possible, to write it in one line without any nested
> functions in WHERE? If it's possible I'd prefer that...
> 
> any idea?
> 
> Thanks
> 
> 
> 
> -- View this message in context:
> http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158p5730170.html
>
> 
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
> 
> _______________________________________________ Haskell-Cafe
> mailing list Haskell-Cafe <at> haskell.org 
> http://www.haskell.org/mailman/listinfo/haskell-cafe
> 
I'm sorry but you should at least attempt a solution yourself and ask
for help if you get stuck. Furthermore, this topic is a bit more
appropriate on the Haskell beginners mailing list. You should also
probably read a bit more about the language before asking about the
very basics (such as the `||' operator).

You can define any non-recursive functions inline with lambda
functions. There really is no reason to avoid `where' just for the
sake of having it inline though. It's bad practice to have very long
lines and it's horrible for readability.

--

-- 
Mateusz K.
John | 14 May 18:53 2013
Picon

Re: list comprehension doesn't work

thanks for your tips.

As I said, I'm at the very beginning of Haskell. I try it to understand as
much as I can, however the topic is very new to me. Sorry about my silly
questions...

You said, their is a mailing list for beginner? Could you please tell me I
get to that?

Thanks

--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158p5730172.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
Mateusz Kowalczyk | 14 May 19:10 2013
Picon

Re: list comprehension doesn't work


On 14/05/13 17:53, John wrote:
> thanks for your tips.
> 
> As I said, I'm at the very beginning of Haskell. I try it to
> understand as much as I can, however the topic is very new to me.
> Sorry about my silly questions...
> 
> You said, their is a mailing list for beginner? Could you please
> tell me I get to that?
> 
> Thanks
> 
> 
> 
> -- View this message in context:
> http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158p5730172.html
>
> 
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
> 
> _______________________________________________ Haskell-Cafe
> mailing list Haskell-Cafe <at> haskell.org 
> http://www.haskell.org/mailman/listinfo/haskell-cafe
> 
You can sign up to the list at [1]. If you're new to Haskell itself, I
recommend that you first read [2] before asking questions that are out
in the open for anyone to discover on their first few days with the
language.

Good luck
[1] - http://www.haskell.org/mailman/listinfo/beginners
[2] - http://learnyouahaskell.com/

--

-- 
Mateusz K.
Jerzy Karczmarczuk | 14 May 19:18 2013
Picon

Re: list comprehension doesn't work

MATEUSZ,

There is nothing wrong with sending beginner questions to h-café!
After all, a FRIENDLY community is for whom? For Simon PJ only?

Notice that "John" got more than a dozen answers, people TRY to help him 
anyway.
==

On the other hand, the original requester *should* have thought on:

1. Putting down in a concise, but explicit manner what was for him the 
expected result. And also:
2. Writing what were the errors signalled by the system.

But no, we had just "help!, nothing works".  This should be avoided, 
some people are reluctant to analyze situations too obscure, even if one 
"almost-syntax" error was clear...

Jerzy Karczmarczuk
Mateusz Kowalczyk | 15 May 00:00 2013
Picon

Re: list comprehension doesn't work


On 14/05/13 18:18, Jerzy Karczmarczuk wrote:
> MATEUSZ,
> 
> There is nothing wrong with sending beginner questions to h-café! 
> After all, a FRIENDLY community is for whom? For Simon PJ only?
> 
> Notice that "John" got more than a dozen answers, people TRY to
> help him anyway. ==
> 
> On the other hand, the original requester *should* have thought
> on:
> 
> 1. Putting down in a concise, but explicit manner what was for him
> the expected result. And also: 2. Writing what were the errors
> signalled by the system.
> 
> But no, we had just "help!, nothing works".  This should be
> avoided, some people are reluctant to analyze situations too
> obscure, even if one "almost-syntax" error was clear...
> 
> Jerzy Karczmarczuk
> 
> 
> _______________________________________________ Haskell-Cafe
> mailing list Haskell-Cafe <at> haskell.org 
> http://www.haskell.org/mailman/listinfo/haskell-cafe
> 
Sorry but I never said these questions don't belong here. I simply
said that beginner questions are more appropriate on a list created
specifically for that purpose. You might argue what `beginner' means
per-person basis but I don't think there's much to argue over in this
very case. I simply pointed the OP to the list (and some resources)
when he asked about it as he wasn't aware it existed.

John got more than a dozen answers _after_ he showed that he tried
something. The post I was replying to simply had no visible attempt at
a problem and it was something that is covered in pretty much every
Haskell tutorial.

I don't think my post was out of order at all and I don't understand
why it sparked such an... energetic response - that wasn't my intent
at all.

--

-- 
Mateusz K.
Daniel Trstenjak | 15 May 08:13 2013
Picon

Re: list comprehension doesn't work


Hi Mateusz,

> I don't think my post was out of order at all and I don't understand
> why it sparked such an... energetic response - that wasn't my intent
> at all.

A friendly response might contain the things you told John, but it could
also be a bit more empathic, otherwise its easy to perceive it as harsh.

A friendly community is the result of considering this.

Greetings,
Daniel
Daniel Díaz Casanueva | 14 May 19:21 2013
Picon

Re: list comprehension doesn't work

Hi John,


On Tue, May 14, 2013 at 5:41 PM, John <knowledge1202 <at> gmail.com> wrote:
Danny Gratzer wrote
> Well you've deleted the portion of the code referring to x and y.
>
> listPairs = [(a*b, y) | y <- [0..], a <- [0..], b <- [0..], (a*b) > 5,
> (a*b) < 500, (y*y) < 1001, mod y (a*b) == 0]
>
> This will still never terminate however.

oh I see, but as you say it doesn't terminate and I get nothing. Does it
mean, that the function is wrong in this place?

Some questions:
1. Does the order of conditions affect the result at all?
2. The "," means AND or &&, right? So how do you write OR || instead? E.g
z<-[1..10] OR z<-[100..110].
Ofcourse it doesn't relate to this topic, but I wanted to know it.

Since I'm a very beginner I think the approach of Daniel is slightly complex
for me to comprehend, right?
Allthough I tried it, but it says isProduct and isSquer are not in Scope, so
I should define them first in WHERE-Clause right?

Yes. The idea is to reduce a problem to simpler subproblems. It is a common practice while programming, and often will make your code clearer. Where do you find the difficulty? The (incomplete) solution I wrote was:

 [ (x,y) | x <- [6 .. 499] ,  y <- [0 .. 1000] , isProduct x , isSquare y , mod y x == 0 ]

which you can read as:

The list of the pairs of numbers x and y, where x belongs to {6, ... , 499}, y belongs to {0, ... , 1000}, x is a product of two numbers, y is the square of a number and y MOD x is 0.

These look like the conditions you asked for. So you can say that you solved the problem of generating the list, if you know how to decide if a number is a product or a square in the first place. You can define these two functions separately.

isProduct :: Int -> Bool
isProduct n = ...

isSquare :: Int -> Bool
isSquare n = ...

The question of if a number is a product or not is equivalent to the question of checking if a number is prime or not. Indeed, If it is prime, it is not a product of two natural numbers (I am, of course, guessing that you don't want ones in the product). If it is NOT prime, then you can factor the number.

To solve the "isSquare" problem, you can just check if it coincides with the square of any number below the square root of the number in question.

I think you don't want an explicit solution, but some hints, so you can explore the problem deeper and learn from it.

I must also note, as other people have already done, that this questions fits in better in the Haskell-Beginners mailing list.


I hope this works for you,
Daniel Díaz.
 

Thanks again to all




--
View this message in context: http://haskell.1045720.n5.nabble.com/list-comprehension-doesn-t-work-tp5730158p5730167.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



--
E-mail sent by Daniel Díaz Casanueva

let f x = x in x
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Mark Lentczner | 14 May 23:13 2013
Picon

Re: list comprehension doesn't work

module Stuff where

import Data.List

-- Let's translate your specification directly into a list comprehension
s1 :: [(Integer, Integer)]
s1 = [(x,y)
        | x <- [1..]        -- for this problem, better to have 0 ∉ N
        , let a = 1         -- if 1 ∈ N, 
        , let b = x         -- then by setting a = 1 and b = x
        , x == a * b        -- we can have any x ∈ N, x = a · b, where a, b ∈ N
        , x > 5
        , x < 500
        , c <- [1..]        -- this is a problem, see below
        , let y = c * c
        , y <= 1000
        , y `mod` x == 0
        ]

-- Something is wrong with the a*b constraint as specified, since it has no
-- effect. I bet the intention was that x is a composite number, not prime.
-- We could insert a primality test, but it is easier to construct all possible
-- x values that are clearly the composite of two numbers greater than 1: 
s2 :: [(Integer, Integer)]
s2 = [(x,y)
        | a <- [2..499]     -- we know the upper bound
        , b <- [2..a]       -- a 'diagonalization', since one of the two numbers
        , let x = a * b     -- must be same or smaller, let it be b
        , x > 5
        , x < 500
        , c <- [1..]        -- still a problem
        , let y = c * c
        , y < 1000
        , y `mod` x == 0
        ]

-- Let's fix the problem of having an infinite source in the middle of the
-- the comprehension.
-- 
-- To understand the problem, think about how the comprehension is evaluated.
-- The whole expression after the vertical bar is a value in the list monad.
-- You can think of each comma separated term being handled left to right. If
-- the term is an <-, then one value from the list is bound to the variable
-- on the right, and the next term considered. If the term is a let, then it
-- is just a binding. Finally, if the term is a condition, then if it holds,
-- it goes on, otherwise it "backtracks". If the end of the term list is reached
-- then the expression before the vertical bar as produced as a value in the
-- result list... and then we "backtrack". Backtracking has the effect of
-- backing up to the previous <- and binding the next value in that list. If
-- it runs out, then backtrack further.
-- 
-- The problem is that if there is an infinite list in the middle of the
-- comprehension, evaluation will never backtrack before it, as that list
-- never ends. And hence, any prior <- will never bind its next value.
-- 
-- The fix is to have only finite lists in the middle. Here, we can fix
-- an upper bound to c.
s3 :: [(Integer, Integer)]
s3 = [(x,y)
        | a <- [2..499]
        , b <- [2..a]
        , let x = a * b
        , x > 5
        , x < 500
        , c <- [1..floor(sqrt 1000 :: Double)]
        , let y = c * c
        , y `mod` x == 0
        ]

-- The above will produce duplicates because there may be more than one way
-- to produce a value x as the product of two values a and b. We can easily
-- de-duplicate them with the library function nub:
s4 :: [(Integer, Integer)]
s4 = nub s3

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Richard A. O'Keefe | 15 May 02:20 2013
Picon

Re: list comprehension doesn't work


On 15/05/2013, at 2:57 AM, John wrote:

> Hi,
> 
> I have to write a function which returns a list of all pairs (x,y) where x,
> y ∈ N AND:
> –  x is the product of two natural numbers (x = a · b, where a, b ∈ N) AND
> –  x is really bigger than 5 but really smaller than 500, AND
> –  y is a squer number (y = c² where c ∈ N) NOT greater than 1000, AND
> –  x is a divisor of y.

Step 1.  If   a >= 0 and b >= 0 & x = a*b & x < 500 & x > 5
         then a > 0 and a < 500
          and b > 0 and b < 500.

This suggests something like

    xs = [x |
          a <- [1..499],
          b <- [1..499],
          let x = a*b,
          5 < x, x < 500
         ]

Step 2.
However, that will generate duplicates.  If a*b = x then b*a = x, and
non-square values of x will be generated twice.
Let's just filter [6..499].
If x is in that range, and a is a number in the range [1..x-1],
and x `mod` a is zero, then x = a*b for some integer b, and b will
_have_ to be in the range you are looking for.

    xs = [x |
          x <- [6..499],
          or [x `mod` a == 0 | a <- [1..x-1]]
         ]

xs has 494 elements.  At first I was surprised to see that 7 was in
the list.  However, if x = 7, a = 7, b = 1, then indeed a and b are
natural numbers and x is there product, so _every_ number in the
range 6..499 qualifies.

Step 3.  If   c >= 0 and y = c*c and y <= 1000
         then c >= 0 and c <= 31

This gives us

    ys = [c*c | c <- [0..31]]

or even

    ys = map (^2) [0..31]

which of course has 32 elements.

Step 4.

Now all that's left to test is whether x divides some y:

    [(x,y) | x <- xs, y <- ys, y `mod` x == 0

pairs :: [(Int,Int)]

pairs = [(x,y) | x <- xs, y <- ys, y `div` x == 0]
  where xs = [x | x <- [6..499], or [x `mod` a == 0 | a <- [1..x-1]]]
        ys = [c*c | c <- [0..31]]

This has 641 elements.

If the definition was supposed to be that x is a *composite* number
with factors a, b, then we need to search for "a" in the range [2..x1].

Using

pairs = [(x,y) | x <- xs, y <- ys, y `div` x == 0]
  where xs = [x | x <- [6..499], or [x `mod` a == 0 | a <- [2..x-1]]]
        ys = [c*c | c <- [0..31]]                       --  ^

xs has 402 elements and pairs has 546 elements.

> listPairs :: [(Int, Int)]
> listPairs = [(x,y) | x<-[0..], y<-[0..], x<-[0..]*[0..], x > 5, x < 500,
> (y*y) < 1001, mod y x == 0]
> 
> However it doesn't work unfortunatly 
> 
> Could anyone tell me where my mistake is?

One mistake is that [0..]*[0..] is a type error.
* wants a pair of numbers, and [0..] is not a number.
(There are modules that make lists "numbers", but then
 as*bs is usually the same as zipWith (*) as bs, which
 is not what you want anyway.)

The main mistake is that

[x | x <- [0..], x > 5, x < 500]

is equivalent to

    for (x = 0; true; x++) if (x > 5 && x < 500) yield x

That is, the [0..] part is happy to keep on generating
increasing integers, it neither knows, nor does it care,
that there is an x < 500 test downstream.

If you really want an infinite set searched, by all means
use [0..].  But if you only want a finite range, put BOTH
bounds in the interval so that it will stop.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane