Reputation: 89
How can one pass output from a function as an input in another function.
For example I have those two functions
collatz :: (Integral a) => a -> [a]
collatz 1 = [1]
collatz n
|even n = n:collatz (n `div` 2)
|odd n = n:collatz (n*3 + 1)
And my another function
length' [] = 0
length' (x:xs) = 1 + length' xs
I want to calculate the length of a list, which was output from my collatz function.
finally I want calculate completely this
numLongChains :: Int
numLongChains = length (filter isLong (map collatz [1..100]))
where isLong xs = length xs > 15
But step by step.
Upvotes: 2
Views: 2243
Reputation: 647
You are talking about function composition:
-- assuming signature length' :: [a] -> Int
composed :: (Integral a) => a -> Int
composed = length' . collatz
I am not sure what you mean by 'step by step', but for your second question, it would be:
numLongChains :: (Integral a) => [a] -> Int
numLongChains = length' . (filter isLong) . (map collatz)
where isLong xs = length' xs > 15
I made it a unary function so it can work with any list, not just [1..100]
.
Upvotes: 5
Reputation: 15605
The length'
of the collatz
sequence for n
is \n -> length' (collatz n)
. This pattern is so common that we gave it a name: f . g = \x -> f (g x)
. We call this "function composition". Replacing f
, g
, and x
above with length'
, collatz
, and n
, we get length' . collatz = \n -> length' (collatz n)
. So:
collatzLength = length' . collatz
As an aside, instead of writing isLong
as you do, we can use function composition here too, albeit in a slightly less obvious way:
isLong xs = length' xs > 15
isLong = \xs -> length' xs > 15
isLong = \xs -> (>) (length' xs) 15
isLong = \xs -> (> 15) (length' xs) -- this is the less obvious bit
isLong = (> 15) . length'
So the question "is the collatz sequence for the number n longer than 15?" can now be written as:
isLongSequence = isLong . collatz
So the long sequences for the numbers [1..100]
are
filter isLongSequence [1..100]
or with
longSequences = filter isLongSequence
it's
longSequences [1..100]
now, we can write numLongChains
as
numLongChains = length' . longSequences
The number of long chains is the number (length) of (the list of) long sequences.
Now, to show that this is equivalent to your definition, you need to know a rule (theorem) about map and filter:
filter p . map f = filter (p . f)
So
\xs -> filter isLong (map collatz xs)
is the same as
filter isLong . map collatz
is the same as
filter (isLong . collatz)
is the same as
filter isLongSequence
is the same as
longSequences
Upvotes: 2