Performing Haskell Mini Functions

I am trying to use this function and make a small implementation using iteration and takeWhile. It should not use these functions, I'm just trying to turn it into a single line. I can see the template in it, but I canโ€™t use it without contributing the same code, only with repetition instead of recursion.

fun2 :: Integer -> Integer fun2 1 = 0 fun2 n | even n = n + fun2 (n `div` 2) | otherwise = fun2 (3 * n + 1) 

Any help would be great. I struggled with this watch. Thanks

+4
source share
3 answers

If you want to do this with iterate , the key should break it into smaller logical parts:

  • generate a sequence using the rule

    a k + 1 = a k / 2 if a k is even

    a k + 1 = 3a k +1 if a k is odd

  • stop the sequence at j = 1 (all this if the collatz hypothesis is true).

  • filter out even elements on the way
  • sum them up

So this will be:

  f = sum . filter even . takeWhile (>1) . iterate (\n -> if even n then n `div` 2 else 3*n + 1) 

However, I think this would be clearer with a helper function

  f = sum . filter even . takeWhile (>1) . iterate collatz where collatz n | even n = n `div` 2 | otherwise = 3*n + 1 

This may not give you any rows, but converts your recursion into data generation.

+6
source

Firstly, I agree with the tom comment that there is nothing wrong with your four-line version. It is beautifully readable. However, it is a fun exercise from time to time to turn Haskell functions into one liner. Who knows, you can learn something!

You currently have

 fun 1 = 0 fun n | even n = n + fun (n `div` 2) | otherwise = fun (3 * n + 1) 

You can always convert an expression using protective devices to if

 fun 1 = 0 fun n = if even n then n + fun (n `div` 2) else fun (3 * n + 1) 

You can always convert a series of pattern matches into a case expression:

 fun n = case n of 1 -> 0 _ -> if even n then n + fun (n `div` 2) else fun (3 * n + 1) 

And finally, you can convert the case expression to an if chain (in fact, in the general case, an argument to your function will require an Eq instance, but since you use Integer , it doesnโ€™t matter.

 fun n = if n == 1 then 0 else if even n then n + fun (n `div` 2) else fun (3 * n + 1) 

I think you will agree that this is much less readable than where you started.

+3
source

One insert;)

 fun2 n = if n==1 then 0 else if even n then n + fun2 (n `div` 2) else fun2 (3 * n + 1) 

I feel that without lookup tables this function cannot be implemented without recursion, because the argument passed in recursion seems unpredictable (except for n as powers of 2).

On the other hand, rampion helped me learn something new.

0
source

All Articles