1

I just started to learn Haskell today and is completely overwhelmed by its syntax.

I am trying to apply math calculation to a list of items.

For example, lets say I want to square every item in the list using list comprehension.

My attempt

myfunc (n:lis) = [ k | k <-lis, k == k^k]

result_list = myfunc[1..]

take 10 result_list

My understand of my myfunc code: take a list and loop through elements that is stored in variable k and set k equals to its square.

after i execute the take command, and hit enter, apparently the process is running but does not do anything.

Note that i want to use list comprehension as a way to do it. I can use map do achieve my goal already.

5
  • 1
    No, this is totally wrong. You cannot "set" a variable in Haskell. k == k^k means "k is equal to its own kth power" (it's a boolean condition). There aren't many such numbers out there, and your function just happens to skip the first and only one, so there's no output. Commented Aug 5, 2018 at 19:27
  • @n.m. is (n:lis) equivalent of Java's (for var in array)? Commented Aug 5, 2018 at 19:29
  • If you want to generate a list of squares, you need something like [k^2|k<-lis]. Commented Aug 5, 2018 at 19:29
  • 2
    "is (n:lis) equivalent of Java's " no, they even weren't in the same town. Commented Aug 5, 2018 at 19:30
  • @n.m. thank you for the explination Commented Aug 5, 2018 at 19:43

1 Answer 1

4

You misunderstand the list comprehension.

[ k | k <- lis, k == k^k ]

The k == k^k clause is a filter –– it only keeps elements of the list that satisfy this equation. (== is a comparison operator that returns a bool, which is one hint). The reason you see no output is that there are no numbers in [1..] that satisfy this equation. But we get an infinite loop because we keep checking ever higher numbers to see if they satisfy it.

Something to experiment with

[ k | k <- lis, k < 100 ]

As for how to get a list of squares, use a comprehension like this

[ k^2 | k <- lis ]

If you want something more like your original phrasing, you can make let bindings within a list comprehension:

[ r | k <- lis, let r = k^2 ]

There are other issues with your code, but one baby step at a time! Good luck!

Sign up to request clarification or add additional context in comments.

3 Comments

I dont quite understand the point of (n:lis) in this case. In the working code here: myFunc (n:lis) = [ k^k | k <-lis], N does not seem to function as anything.
@aDev n is the first element of the list (which your function throws away). lis is the tail of the list (everything but the first element). If you want to use the input list as is, use myFunc lis = [ ... ].
[ k | k <- lis, k < 100 ], which can be written filter (<100) lis has a potential problem; it will never stop checking values from lis to see if they happen to satisfy <100. If we know they grow monotonically, we can get a terminating list instead using takeWhile (<100) lis. In this example, we expect the take 10 in the original code to make sure we don't see the part where the filter runs indefinitely without completing (which happened immediately for the original comprehension).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.