I found this implementation of the average function:
avg :: [Int] -> Int
avg = div . sum <*> length
How does this work? I looked at the function that was produced as a result of div . sum:
(div . sum) :: (Integral a, Foldable t) => t a -> a -> a
I understand that, but I'm unable to tell how <*> length does the work.
Count the number of elements in the rates list: let countRates = length rates. Divide sumRates by countRates . But before you do that, convert countRates to a floating point number. Otherwise Haskell will complain: sumRates / (fromIntegral countRates)
() is very often used as the result of something that has no interesting result. For example, an IO action that is supposed to perform some I/O and terminate without producing a result will typically have type IO () .
The workhorse for converting from integral types is fromIntegral , which will convert from any Integral type into any Num eric type (which includes Int , Integer , Rational , and Double ): fromIntegral :: (Num b, Integral a) => a -> b.
You can calculate the average of the second elements of the list of tuples, you don't need to do the sum yourself because Scala has a builtin function for that. First we need to transform the list of tuples to a list of Int values, we can do that using the map function as shown below. val average = list.
<*> :: Applicative f => f (a -> b) -> f a -> f b is the sequential application function that works on an Applicative structure. For a function, this is implemented as [src]:
instance Applicative ((->) r) where pure = const (<*>) f g x = f x (g x) liftA2 q f g x = q (f x) (g x)
so f <*> g is short for \x -> f x (g x). This thus means that in the case of avg:
avg = div . sum <*> length
is equivalent to:
avg x = (div . sum) x (length x)
which is thus equivalent to:
avg x = div (sum x) (length x)
so it divides the sum x with length x.
I'm not a fan of this particular pointfree-trick. It uses the Applicative (a->) instance as a “fanout”, to pass the argument to two separate functions. Essentially those two functions are sum and length, and the results are then combined back by div, which can be expressed nicely with arrow combinators (albeit a bit more verbose, because arrows don't really play in Haskell's default curried style):
import Control.Arrow
avg = uncurry div . (sum &&& length)
In the applicative trick, you merge the combining function into the first argument-sharing one. So div . sum in this case, and the result of the other function length is then passed into the second argument of the first function.
You can also use
avg = liftA2 div sum length
which uses the Applicative instance too.
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