In the following snippet, you can see my two collatz functions I wrote in Haskell. For the recursive application I used parentheses in the first example (collatz) to get the right precedence.
As I have just learnt function application with $, I tried to rewrite the function (collatz') using that thing. However, I encounter the following error:
Couldn't match expected type `[a]' against inferred type `a1 -> [a1]' In the second argument of `(:)', namely `collatz'' In the first argument of `($)', namely `n : collatz'' In the expression: n : collatz' $ n `div` 2
collatz :: (Integral a) => a -> [a]
collatz 1 = [1]
collatz n | even n = n : collatz (n `div` 2)
| otherwise = n : collatz (n * 3 + 1)
collatz' :: (Integral a) => a -> [a]
collatz' 1 = [1]
collatz' n | even n = n : collatz' $ n `div` 2
| otherwise = n : collatz' $ n * 3 + 1
It seamed weird to me that this didn't work. So I tried a similar example that worked:
True : [even $ 3 `div` 3]
I'd appreciate it, if somebody could take a look at it and tell me what I'm doing wrong.
$
has lower precedence then :
(and also anything else) so your function is parsing as
(n : collatz') $ (n `div` 2)
This leads to your type error. The second argument of :
expects a list but you are passing the collatz function instead.
If you still want to avoid the parenthesis around the 3n+1 part you can do something like the following
(n:) . collatz' $ n `div` 2
n : (collatz' $ n `div` 2)
although these are not necessarily cleaner then the original. In case you are wondering, the (n:)
in the first example is a syntactic sugar for \x -> n : x
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With