I came across a Haskell function that tells whether a list is sorted, and I'm having trouble understanding how it works.
The code in question is
f = zipWith (<=) <*> tail
which I understand to be equivalent (in point-ful style) to
f' xs = zipWith (<=) xs (tail xs)
and as an example returns
f [4, 5, 1] == [True,False]
I take it that it has something to do with the list monad and sequential application, but would appreciate if someone could make the meaning more clear to me. What exactly is <*>
doing here?
The <*>
here isn't acting on the [a]
applicative, it's acting in the (->) a
applicative instance.
Essentially
instance Applicative ((->) a) where
pure = const -- same as monadic return
f <*> a = \x -> f x (a x)
So it acts like function application, but also wraps the application in a function and gives the argument to both sides.
So expanding your function
zipWith (<=) <*> tail
\x -> zipWith (<=) x (tail x)
\(x:xs) -> zipWith (<=) (x:xs) xs
In general it's correct to view <*>
as just function application + some extra goodies. You can almost read it as whitespace!
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