Ziplists with longest-style applicative behaviour - haskell

Is it possible in Haskell do define a type similar to ziplist, in which operation a <*> b will produce list which is as long as the longest of a and b.
It is clear that in this case we must assume that a and b are lists over something like Monoid, so tentative declaration is:
instance Monoid a => Applicative (ZList a) where ...
which clearly will not typecheck. Another tentative approach is to use GADTs with constrained constructors, something like
data ZList a where
Z:: ZList a
S:: Monoid a => a-> (ZList a) -> (ZList a)
but then I stuck on a stage of making it Functor because we cannot guarantee that in fmap::(a -> b) -> f a -> f b, b will be Monoid.
Clearly, this question extends to wider class of algebraic datatypes for which we want to define "pointwise" applicative behavior in which we produce output with shape similar to the union of shapes of the arguments.

First, what you really want is probably Default, not Monoid - you have no use for mappend.
I don't think anything useful is possible in Applicative itself. That said, I can define a version of (<*>) (called (<#>)) with extra constraints that lets me do what I think you have in mind.
Why there is no point in making a new data type
First, suppose we were to take the ExistentialQuantification route in hopes of pushing our constraints into the data and having legitimate instances of Functor and Applicative. That blows up as soon as we try to define fmap:
{-# LANGUAGE ExistentialQuantification #-}
data ZipMonList a = Default a => ZipMonList [a]
-- Woops, we still need a constraint for `Default b`
fmap :: Default b => (a -> b) -> ZipMonList a -> ZipMonList b
fmap f (ZipMonList xs) = ZipMonList (f xs)
So, with that settled, let's stick to the ZipList type (since we want the same (<$>) anyways) and just define our new constrained version of (<*>), called (<#>).
Make (<#>) for ZipList
Underlying ZipLists (<*>) is the zipWith function. We need something similar for (<#>), but that extends lists. Then, (<#>) looks a lot like (<*>):
import Control.Applicative (ZipList(..))
import Data.Default
-- Like 'zipWith', but has maximum length
zipWith' :: (Default a, Default b) => (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' f [] [] = []
zipWith' f (x:xs) [] = f x def : zipWith' f xs []
zipWith' f [] (y:ys) = f def y : zipWith' f [] ys
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
-- same fixity as <*>
infixl 4 <#>
-- like '(<*>)', but uses 'zipWith'' instead of 'zipWith'
(<#>) :: (Default a, Default b) => ZipList (a -> b) -> ZipList a -> ZipList b
ZipList fs <#> ZipList xs = ZipList (zipWith' id fs xs)
And I can do a test run on tuples:
ghci> (,,) <$> ZipList [1.2,3.4,5.6,7.8,9.1] <#> ZipList [[(),()],[()],[(),(),()]] <#> ZipList [1,2,3,4]
ZipList {getZipList = [(1.2,[(),()],1),(3.4,[()],2),(5.6,[(),(),()],3),(7.8,[],4),(9.1,[],0)]}
Key takeaway point: this is not an Applicative, but still doable.

I just have a few notes for you, things to think about.
The definition of the typeclass that will allow this is known as the Constrained Typeclass Problem, and there have been a few approaches.
I notice that you have only specified that the resulting list should be as long as the longer of the two lists, but you haven't said what the remaining elements should be. At that point you might as well use the applicative
ZipList :*: Const (MaxPos Int)
(where :*: is functor product, and MaxPos is a monoid I just made up taking the maximum on nonnegative numbers) which keeps track of the "length" separately, because the remaining elements will be meaningless.
Rather, I suspect you mean something where the remaining elements are preserved in some sense, i.e. so
(*) <$> [2,3,4] <*> [4] = [8,3,4]
and also
(+) <$> [2,3,4] <*> [4] = [6,3,4]
So if we were to "fill in" missing elements in the former case we should fill them in with 1, and in the latter we should fill them in with 0. This starts to show us a different aspect of the problem; we need to pick identity elements based on the operation, or just "leave alone" the remaining elements (which constrains the operations to type a -> a -> a). This is looking less possible, it'd be interesting to explore more. That's all I've got for now, sorry.

Related

Cartesian product set generation [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
I am trying to create a Haskell function to generate a Cartesian product of two lists
Here's my attempt:
cartesianProduct :: (a -> b -> c) -> [a] -> [b] -> [c]
cartesianProduct f x [] = x
cartesianProduct f y [] = y
cartesianProduct = f x y unionHelper func1 f xs ys
If you're in a hurry, then the function is called liftA2 and it's actually built-in.
sort $ liftA2 (*) [1,2,4] [1,3,9] -- [1,2,3,4,6,9,12,18,36]
But, of course, that's not very enlightening, so let's talk about how we might do it ourselves.
The list type, [], is a functor. We can implement fmap directly using recursion.
fmap :: (a -> b) -> [a] -> [b]
fmap _ [] = []
fmap f (x:xs) = f x : fmap f xs
Now we have a way of to do something for each element of a list. Great, that's how we'll apply our final operation, but we need to generate all of the argument lists as well. Specifically, we want to produce the Cartesian product.
cross :: [a] -> [b] -> [(a, b)]
And we can do so recursively as well, using our fmap function to help out.
cross :: [a] -> [b] -> [(a, b)]
cross [] _ = []
cross (x:xs) ys = fmap ((,) x) ys ++ cross xs ys
Recursion on the first element. If the first argument is empty, then the Cartesian product is empty. If the first argument is nonempty, then the result should consist of the head paired with each (via fmap) element of the second argument, followed by the Cartesian product of the tail with the second list.
Now we have a way to get a [(Int, Int)]. And we want to multiply those elements, so it's just a matter of tying it all together.
apply2 :: (a -> b -> c) -> [a] -> [b] -> [c]
apply2 f xs ys = fmap (\(x, y) -> f x y) $ cross xs ys
Take the Cartesian product of the two lists, then apply our function f (uncurried) to each element.
This gives us our result, in a slightly different order than in your example. But it looks like you're sorting the results anyway, rather than producing them in an algorithmic order.
sort $ apply2 (*) [1,2,4] [1,3,9] -- [1,2,3,4,6,9,12,18,36]
Now, let's talk about why liftA2 works. The list type is an example of an applicative functor, represented by the Applicative typeclass. Whereas fmap (which is part of Functor) takes a single function and maps it over a functor (in our case, over several elements of a list), the fundamental applicative operation is <*> (pronounced "ap"), whose signature is
fmap :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Instead of mapping a single simple function over a functor value f a, we're mapping a function inside the functor f (a -> b) over a value also inside the functor f a. Now, this is a jumble of words, but in the case of lists it looks like
fmap :: (a -> b) -> [a] -> [b]
(<*>) :: [a -> b] -> [a] -> [b]
Rather than applying a single function to several elements, we're applying several functions to several elements. (<*>) is actually just our cross function written in a slightly different way. It's combining two lists using every combination to produce a result of some type. (In fact, the relationship between our cross and the applicative (<*>) is rather deep mathematically, due to the fact that (->) and (,) are adjoint to each other, but that's getting off track)
So (<*>) is just cross by another name. And liftA2 is defined as (something equivalent to)
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = fmap f a <*> b
It's just doing fmap and (<*>), which is basically what our apply2 function was doing to begin with. Again, it's slightly shuffled around since we're using (->) rather than (,) (since our "ap" operator applies a function rather than building a tuple), but it's exactly the same idea.
Certainly, the liftA2 approach is snazzy and short, but don't let it blind you. There's nothing wrong with a recursive approach, especially as you're learning. If apply2 makes more sense to you and my explanation above of the applicative functors was nonsense, then go for it. You can go a long way in Haskell learning about recursion and data structures before really grokking functors, and that's fine. But when you're ready, I recommend Typeclassopedia for an excellent summary of the Haskell typeclasses that represent functors, applicative functors, monads, and all of the other lesser-known abstractions available to the programmer.
Good luck, and happy coding!

Haskell quickBatch: Testing ZipList Monoid at mconcat results in stack overflow

i've created orphaned instances for ZipList Semigroup and Monoid. However, when I run the tests from quickBatch on monoid, at the mconcat test, there is a stack overflow error. How do I resolve this error? Why is there such an error? Is it due to pure mempty, which I do not quite understand as I got this mostly from HaskellBook Chapter 17 Applicative section 17.8 ZipList Monoid?
zl :: ZipList (Sum Int)
zl = ZipList [1,1 :: Sum Int]
instance Semigroup a
=> Semigroup (ZipList a) where
(<>) = liftA2 (<>)
instance (Eq a, Monoid a)
=> Monoid (ZipList a) where
mempty = pure mempty
mappend = (<>)
mconcat as =
foldr mappend mempty as
main :: IO ()
main = do
quickBatch $ monoid zl
Yes, the error is due to pure mempty, but that doesn't mean pure mempty is wrong. Let's look there first.
It helps a lot to look at the types involved in the definition mempty = pure mempty:
mempty :: ZipList a
mempty = (pure :: a -> ZipList a) (mempty :: a)
Basically, we're going to use the pure operation to create a ZipList out of the mempty of type a. It helps from here to look at the definition of pure for ZipList:
pure :: a -> ZipList a
pure x = ZipList (repeat x)
In total, mempty for ZipList a is going to be a ZipList containing the infinitely repeating list of mempty values of the underlying type a.
Back to this error you're getting. When you try to run the test monoid over ZipList (Sum Int), QuickCheck is going to test a sequence of properties.
The first two check the left identity and right identity properties. What these do is generate values of type x :: ZipList (Sum Int) and verify that x <> mempty = mempty <> x = x.
The third checks that for any two values x, y :: ZipList (Sum Int), we have that x mappend y = x <> y.
The fourth checks that for any list of values x :: [ZipList (Sum Int)], folding these with mappend is the same as mconcating them.
Before I continue, it's really important to note that when I say "for any value", I really mean that QuickCheck is using the Arbitrary instance of the said type to generate values of that type. Furthermore, the Arbitrary instance for ZipList a is the same as the Arbitrary instance for [a] but then wrapped in ZipList. Lastly, the Arbitrary instance for [a] will never produce an infinite list (because those will cause problems when you're checking for equality, like going into an infinite loop or overflowing the stack), so these "for any values" of type ZipList (Sum Int) will never be infinite either.
Specifically, this means that QuickCheck will never arbitrarily generate the value mempty :: ZipList a because this is an infinite list.
So why do the first 3 pass but the last one fails with a stack overflow? In the first three tests, we never end up trying to compare an infinite list to an infinite list. Let's see why not.
In the first two tests, we're looking at x <> mempty == x and mempty <> x == x. In both cases, x is one of our "arbitrary" values, which will never be infinite, so this equality will never go into an infinite loop.
In the third test, we're generating two finite ZipLists x and y and mappending them together. Nothing about this will be infinite.
In the third case, we're generating a list of ZipLists and mconcatenating the list. But, what happens if the list is empty? Well, mconcat [] = mempty, and folding an empty list produces mempty. This means, if the empty list is generated as the arbitrary input (which is perfectly possible), then the test will try to confirm that an infinite list is equal to another infinite list, which will always result in a stack overflow or black hole.
How can you fix this? I can come up with two methods:
You can define your own version of EqProp for ZipList so that it only compares equality on some finite prefix of the list. This would likely involve making a newtype wrapper (perhaps newtype MonZipList a = MonZipList (ZipList a)), deriving a bunch of instances, and then writing an EqProp one by hand. This will probably work but is a little inelegant.
You can write your own version of monoid that uses a different version of the fourth test. For instance, if you restrict it so that the test only uses non-empty lists, then you won't have any problem. To do this, you should start by looking at the definition of the monoid property tests. Notice that it currently defines the "mconcat" property as property mconcatP where
mconcatP :: [a] -> Property
mconcatP as = mconcat as =-= foldr mappend mempty as
Using QuickCheck's own NonEmptyList class, you can rewrite this for your purposes as:
mconcatP :: NonEmptyList a -> Property
mconcatP (NonEmptyList as) = mconcat as =-= foldr mappend mempty as
Obviously, this is a slightly weaker condition, but at least it's one that won't hang.
As an aside, this definition of Monoid for ZipList is inconsistent with the definition of Alternative for ZipList.
I would propose instead:
instance Semigroup a => Semigroup (ZipList a) where
ZipList [] <> ZipList ys = ZipList ys
ZipList xs <> ZipList [] = ZipList xs
ZipList (x:xs) <> ZipList (y:ys) = ZipList (x <> y : getZipList (ZipList xs <> ZipList ys))
instance Semigroup a => Monoid (ZipList a) where
mempty = ZipList []
There is no formal requirement that empty in an Alternative instance be the same as mempty in Monoid, but without an extremely good reason to do so I wouldn't choose otherwise.

How can I implement generalized "zipn" and "unzipn" in Haskell?

I find this documentation in the basic Haskell libraries:
zip :: [a] -> [b] -> [(a, b)]
zip takes two lists and returns a list of corresponding pairs. If one input list is short, excess elements of the longer list are discarded.
zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
zip3 takes three lists and returns a list of triples, analogous to zip.
zip4 :: [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
The zip4 function takes four lists and returns a list of quadruples, analogous to zip.
[...snip...]
unzip :: [(a, b)] -> ([a], [b])
unzip transforms a list of pairs into a list of first components and a list of second components.
unzip3 :: [(a, b, c)] -> ([a], [b], [c])
The unzip3 function takes a list of triples and returns three lists, analogous to unzip.
unzip4 :: [(a, b, c, d)] -> ([a], [b], [c], [d])
The unzip4 function takes a list of quadruples and returns four lists, analogous to unzip.
... and so on, up to zip7 and unzip7.
Is this a fundamental limitation of Haskell's type system? Or is there a way to implement zip and unzip once, to work on different configurations of input?
This is one very useful aspect of applicatives. Check out ZipList which is just a newtype wrapper around a simple list. The reason for the wrapper is that ZipList has an applicative instance for, you guessed it, zipping lists together. Then, if you want zip7 as bs cs ds es fs gs hs, you can just do something like
(,,,,,,) <$> as <*> bs <*> cs <*> ds <*> es <*> fs <*> gs <*> hs
As you can tell, this mechanism is meant to be also for extending zipWith, which is a general case of zip. To be honest, I think we should rip out all of the zipN functions and teach people the above instead. zip itself is fine, but beyond that...
Template Haskell solution
As the comments and other answers indicate, this is not a particularly satisfying answer. The one thing I was expecting someone else to implement was a TemplateHaskell version of zip and unzip. As no one has done so yet, here it is.
All it does is mechanically produce AST for zip or unzip functions. The idea behind zip is to use ZipList and behind unzip is to use foldr:
zip as ... zs === \as ... zs -> getZipList $ (, ... ,) <$> ZipList as <*> ... <*> ZipList zs
unzip === foldr (\ (a, ... ,z) ~(as, ... ,zs) -> (a:as, ... ,z:zs) ) ([], ... ,[])
The implementation looks like this.
{-# LANGUAGE TemplateHaskell #-}
module Zip (zip, unzip) where
import Prelude hiding (zip, unzip)
import Language.Haskell.TH
import Control.Monad
import Control.Applicative (ZipList(..))
-- | Given number, produces the `zip` function of corresponding arity
zip :: Int -> Q Exp
zip n = do
lists <- replicateM n (newName "xs")
lamE (varP <$> lists)
[| getZipList $
$(foldl (\a b -> [| $a <*> ZipList $(varE b) |])
[| pure $(conE (tupleDataName n)) |]
lists) |]
-- | Given number, produces the `unzip` function of corresponding arity
unzip :: Int -> Q Exp
unzip n = do
heads <- replicateM n (newName "x")
tails <- replicateM n (newName "xs")
[| foldr (\ $(tupP (varP <$> heads)) ~ $(tupP (varP <$> tails)) ->
$(tupE (zipWith (\x xs -> [| $x : $xs |])
(varE <$> heads)
(varE <$> tails))))
$(tupE (replicate n [| [] |])) |]
You can try this at GHCi:
ghci> :set -XTemplateHaskell
ghci> $(zip 3) [1..10] "abcd" [4,6..]
[(1,'a',4),(2,'b',6),(3,'c',8),(4,'d',10)]
ghci> $(unzip 3) [(1,'a',4),(2,'b',6),(3,'c',8),(4,'d',10)]
([1,2,3,4],"abcd",[4,6,8,10])
This is a zipN function that depends on the machinery of the generics-sop package:
{-# language TypeFamilies #-}
{-# language DataKinds #-}
{-# language TypeApplications #-}
import Control.Applicative
import Generics.SOP
-- "a" is some single-constructor product type, like some form of n-ary tuple
-- "xs" is a type-level list of the types of the elements of "a"
zipN :: (Generic a, Code a ~ '[ xs ]) => NP [] xs -> [a]
zipN np = to . SOP . Z <$> getZipList (hsequence (hliftA ZipList np))
main :: IO ()
main = do
let zipped = zipN #(_,_,_) ([1,2,3,4,5,6] :* ['a','b','c'] :* [True,False] :* Nil)
print $ zipped
The result:
[(1,'a',True),(2,'b',False)]
This solution has two disadvantages:
You have to wrap the argument lists in the special NP type from generics-sop that is constructed with :* and Nil.
You need to specify somehow that the result value is a list of tuples, and not a list of some other Generic-compatible type. Here, it is done with the #(_,_,_) type application.
2-ary, 3-ary.. n-ary tuples are all distinct data types, so you can't handle them uniformly directly, but you can introduce a type class that provides an interface that allows to define generic zip and unzip. Here is how it looks for generic unzip:
class Tuple t where
type Map (f :: * -> *) t
nilMap :: Proxy t -> (forall a. f a) -> Map f t
consMap :: (forall a. a -> f a -> f a) -> t -> Map f t -> Map f t
Map maps all types in a tuple type with f. nilMap constructs a Mapped tuple that contains empty values (I have no idea why Haskell requires that Proxy t there). consMap receives a function, a tuple and a Mapped tuple and zip the tuples with the function pointwise. Here is how instances look for 2- and 3-tuples:
instance Tuple (a, b) where
type Map f (a, b) = (f a, f b)
nilMap _ a = (a, a)
consMap f (x, y) (a, b) = (f x a, f y b)
instance Tuple (a, b, c) where
type Map f (a, b, c) = (f a, f b, f c)
nilMap _ a = (a, a, a)
consMap f (x, y, z) (a, b, c) = (f x a, f y b, f z c)
The gunzip itself:
gunzip :: forall t. Tuple t => [t] -> Map [] t
gunzip [] = nilMap (Proxy :: Proxy t) []
gunzip (p:ps) = consMap (:) p (gunzip ps)
This looks a lot like transpose:
transpose :: [[a]] -> [[a]]
transpose [] = repeat [] -- `gunzip` handles this case better
transpose (xs:xss) = zipWith (:) xs (transpose xss)
which it basically is, except with tuples. gunzip can be equivalently defined in terms of foldr as follows:
gunzip :: forall t. Tuple t => [t] -> Map [] t
gunzip = foldr (consMap (:)) $ nilMap (Proxy :: Proxy t) []
To define generic zip we need a type class of splittable data types (is there something like this on Hackage?).
class Splittable f g where
split :: f a -> g a (f a)
E.g. for lists we have
newtype MaybeBoth a b = MaybeBoth { getMaybeBoth :: Maybe (a, b) }
instance Splittable [] MaybeBoth where
split [] = MaybeBoth Nothing
split (x:xs) = MaybeBoth (Just (x, xs))
And here is what we add to the Tuple type class:
splitMap :: (Biapplicative g, Splittable f g) => Proxy (f t) -> Map f t -> g t (Map f t)
The Biapplicative g constraint ensures that it's possible to combine g a b and g c d into g (a, c) (b, d). For 2- and 3- tuples it looks like this:
splitMap _ (a, b) = biliftA2 (,) (,) (split a) (split b)
splitMap _ (a, b, c) = biliftA3 (,,) (,,) (split a) (split b) (split c)
After providing a Biapplicative instance for MaybeBoth
instance Biapplicative MaybeBoth where
bipure x y = MaybeBoth $ Just (x, y)
MaybeBoth f <<*>> MaybeBoth a = MaybeBoth $ uncurry (***) <$> f <*> a
we can finally define gzip:
gzip :: forall t. Tuple t => Map [] t -> [t]
gzip a = maybe [] (\(p, a') -> p : gzip a') . getMaybeBoth $ splitMap (Proxy :: Proxy [t]) a
It repeteadly cuts first elements of lists in a tuple, forms a tuple from them and prepends it to the result.
It should be possible to generalize gunzip by adding a dual to Splittable (Uniteable or something like that), but I'll stop here.
EDIT: I couldn't stop.
You are right that these functions (zip2, zip3 etc.) are all instances of the same pattern and in an ideal world, they should be implementable generically. By the way, as an exercise to the reader, figure out what zip1 and zip0 should be ;).
However, it is hard to implement zipN generically, because the common pattern between all the different cases is rather non-trivial. This does not mean it's impossible to implement it generically, but you'll need some of the more advanced type system features of Haskell GHC to do it.
To be more concrete, zip2, zip3 etc. all have a different number of arguments, making this an instance of "arity-generic programming" (the arity of a function is its number of arguments). As you might expect in the world of functional programming, there is an interesting research paper that covers precisely this topic ("arity-generic programming"), and conveniently, one of their main examples is... zipWithN. It doesn't directly answer your question because it uses Agda rather than Haskell, but you might still find it interesting. In any case, similar ideas can be implemented in terms of one or more of Haskell's GHC's more advanced type-system features (TypeFamilies and DataKinds come to mind). PDF version here.
By the way, this is just about an arity-generic zipWithN. For an arity-generic zipN, you probably need some support from the compiler, particularly an arity-generic interface to the tuple constructor, which I suspect might not be in GHC. This is what I believe augustss's comment to the question and chepner's comment to Alec's answer refer to.

how to implement mapAccumRM?

I asked a similar question before (how to implement mapAccumM?).
I need the one which folds from the right as well (mapAccumR):
mapAccumRM :: (Monad m, Traversable t)
=> (a -> b -> m (a, c)) -> a -> t b -> m (a, t c)
Is there a simple implementation for this?
One approach is to define new instances of Traversable that use the ordering you like. For example, for lists, one might simply define a new type:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Applicative
import Data.Traversable
newtype BackwardsList a = BackwardsList [a]
deriving (Eq, Ord, Read, Show, Functor, Foldable)
instance Traversable BackwardsList where
traverse f (BackwardsList xs) = BackwardsList <$> go xs where
go [] = pure []
go (x:xs) = liftA2 (flip (:)) (go xs) (f x)
In ghci, we can see the difference between this and the standard instance:
> runState (traverse (\_ -> modify (+1) >> get) "hello, world!") 0
([1,2,3,4,5,6,7,8,9,10,11,12,13],13)
> runState (traverse (\_ -> modify (+1) >> get) (BackwardsList "hello, world!")) 0
(BackwardsList [13,12,11,10,9,8,7,6,5,4,3,2,1],13)
This approach is fairly simple; however, it requires a new type (and the associated newtype wrapping/unwrapping garbage) for every new traversal order that you are interested in.
One could consider defining a new type class for ordered traversals. Let's see one way this might be done. We'll need a little prelude:
{-# LANGUAGE Rank2Types, TypeFamilies #-}
import Control.Applicative
import Data.Foldable
import Data.Traversable
import Data.Tree
Most Haskell data types can be viewed as fixed-points of polynomial functors; and the functors that they are fixed-points of are good descriptions of the "spine" of the data structure. We'll abuse this idea to give a concrete way to encode the ordering that should be used during traversal. The class itself looks like this:
type Order t = forall f a. Applicative f => Spine t (f a) (f (t a)) -> f (t a)
class OrderedTraversable t where
data Spine t :: * -> * -> *
otraverse :: Applicative f => Order t -> (a -> f b) -> t a -> f (t b)
Notice that the type of otraverse looks just like the type of traverse, except that it now takes an extra ordering argument. The ordering argument is, in a sense, variadic; since different data types have different numbers of values/children at various places in their structure, and the ordering may care about all of them. (Of special interest is here is the technique of using rank-2 types to prevent an ordering from observing "too much" about a data structure: it can't use special facts about a given instance of Applicative or given kind of element to decide how to traverse a spine, only decisions based on the shape of the spine are allowed.) Let's see a simple example, for lists:
instance OrderedTraversable [] where
-- Cute hack: the normal presentation for the spine of a list uses both
-- a `Cons` and a `Nil`; but parametricity says the only thing an
-- `Order []` can do with a `Nil` is `pure []` anyway. So let's just
-- bake that into `otraverse`.
data Spine [] a r = Cons a r
otraverse order f = go where
go [] = pure []
go (x:xs) = order (Cons (f x) (go xs))
Compare with the implementation of Traversable for lists in the standard library (I have taken the liberty of expanding the definition of foldr to make it more closely match the code above):
instance Traversable [] where
traverse f = go where
go [] = pure []
go (x:xs) = (:) <$> f x <*> go xs
As you can see, the primary difference is that we have abstracted which function to use to combine f x and go xs. We can recover the standard Traversable instance with a "head-first" order. There is also a "last-first" order; and these are basically the only two orders that make sense for lists.
headFirst, lastFirst :: Order []
headFirst (Cons fx fxs) = liftA2 (:) fx fxs
lastFirst (Cons fx fxs) = liftA2 (flip (:)) fxs fx
In ghci, we can now see how they differ:
> runState (traverse (\_ -> modify (+1) >> get) "hello, world!") 0
([1,2,3,4,5,6,7,8,9,10,11,12,13],13)
> runState (otraverse headFirst (\_ -> modify (+1) >> get) "hello, world!") 0
([1,2,3,4,5,6,7,8,9,10,11,12,13],13)
> runState (otraverse lastFirst (\_ -> modify (+1) >> get) "hello, world!") 0
([13,12,11,10,9,8,7,6,5,4,3,2,1],13)
To give another example, here is how you might use this class with rose trees:
instance OrderedTraversable Tree where
data Spine Tree a r = SNode a [r]
otraverse order f = go where
go (Node x ts) = order (SNode (f x) (map go ts))
-- two example orders for trees
prefix, postfix :: Order [] -> Order Tree
prefix list (SNode fx fts) = liftA2 Node fx (otraverse list id fts)
postfix list (SNode fx fts) = liftA2 (flip Node) (otraverse list id fts) fx
Note that there are actually infinitely many "good" ordering functions for rose trees; two that are particularly likely to be what you want are included above.

What does "applicative" mean?

When reading stuff on Haskell, I sometimes come across the adjective "applicative", but I have not been able to find a sufficiently clear definition of this adjective (as opposed to, say, Haskell's Applicative class). I would like to learn to recognize a piece of code/algorithm/data structure, etc. that is "applicative", just like I can recognize one that is "recursive". Some contrasting examples of "applicative" vs. whatever the term intends to draw a distinction from (which I hope is something more meaningful in its own right than "non-applicative") would be much appreciated.
Edit: for example, why was the word "applicative" chosen to name the class, and not some other name? What is it about this class that makes the name Applicative such a good fit for it (even at the price of its obscurity)?
Thanks!
It's not clear what "applicative" is being used to mean without knowing the context.
If it's truly not referring to applicative functors (i.e. Applicative), then it's probably referring to the form of application itself: f a b c is an applicative form, and this is where applicative functors get their name from: f <$> a <*> b <*> c is analogous. (Indeed, idiom brackets take this connection further, by letting you write it as (| f a b c |).)
Similarly, "applicative languages" can be contrasted with languages that are not primarily based on the application of function to argument (usually in prefix form); concatenative ("stack based") languages aren't applicative, for instance.
To answer the question of why applicative functors are called what they are in depth, I recommend reading
Applicative programming with effects; the basic idea is that a lot of situations call for something like "enhanced application": applying pure functions within some effectful context. Compare these definitions of map and mapM:
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]
mapM _ [] = return []
mapM f (x:xs) = do
x' <- f x
xs' <- mapM f xs
return (x' : xs')
with mapA (usually called traverse):
mapA :: (Applicative f) => (a -> f b) -> [a] -> f [b]
mapA _ [] = pure []
mapA f (x:xs) = (:) <$> f x <*> mapA f xs
As you can see, mapA is much more concise, and more obviously related to map (even more so if you use the prefix form of (:) in map too). Indeed, using the applicative functor notation even when you have a full Monad is common in Haskell, since it's often much more clear.
Looking at the definition helps, too:
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Compare the type of (<*>) to the type of application: ($) :: (a -> b) -> a -> b. What Applicative offers is a generalised "lifted" form of application, and code using it is written in an applicative style.
More formally, as mentioned in the paper and pointed out by ertes, Applicative is a generalisation of the SK combinators; pure is a generalisation of K :: a -> (r -> a) (aka const), and (<*>) is a generalisation of S :: (r -> a -> b) -> (r -> a) -> (r -> b). The r -> a part is simply generalised to f a; the original types are obtained with the Applicative instance for ((->) r).
As a practical matter, pure also allows you to write applicative expressions in a more uniform manner: pure f <*> effectful <*> pure x <*> effectful as opposed to (\a b -> f a x b) <$> effectful <*> effectful.
On a more fundamental level one could say that "applicative" means working in some form of the SK calculus. This is also what the Applicative class is about. It gives you the combinators pure (a generalization of K) and <*> (a generalization of S).
Your code is applicative when it is expressed in such a style. For example the code
liftA2 (+) sin cos
is an applicative expression of
\x -> sin x + cos x
Of course in Haskell the Applicative class is the main construct for programming in an applicative style, but even in a monadic or arrowic context you can write applicatively:
return (+) `ap` sin `ap` cos
arr (uncurry (+)) . (sin &&& cos)
Whether the last piece of code is applicative is controversial though, because one might argue that applicative style needs currying to make sense.

Resources