Obviously, if a data structure is a monoid, it's foldable, but is it safe to say if a data structure is foldable, it's a monoid?
https://en.wikibooks.org/wiki/Haskell/Foldable
If a data structure is foldable, is it a monoid?
Your claim "if a data structure is a Monoid then it is Foldable" is not reasonably true. For example:
newtype ActionList a = ActionList (IO [a])
instance Monoid (ActionList a) where
mempty = ActionList (return [])
ActionList a `mappend` ActionList b = ActionList (liftA2 (++) a b)
This is a perfectly good monoid. But because all of its values are under IO, you can't observe any of them from Foldable. The only Foldable instance would be the one that always returns empty (technically this would be valid because foldMap doesn't really have any laws about its validity, but it would hard to say that this is a good instance with a straight face).
The converse, which you are asking about, is also not true. For example:
data TwoThings a = TwoThings a a
This is foldable:
instance Foldable TwoThings where
foldMap f (TwoThings x y) = f x <> f y
However, if something is both a Foldable and a Monoid in any related way, I would expect the following homomorphism laws to hold:
foldMap f mempty = mempty
foldMap f (a <> b) = foldMap f a <> foldMap f b
And we can't get these laws to hold for TwoThings. Notice that foldMap (:[]) a for TwoThings always has two elements. But then the second law has two elements on the left and four on the right. But the laws are not required to find a counterexample, as dfeuer's answer shows.
Here's something Foldable (even Traversable) that has no hope of being a Monoid:
{-# language EmptyCase #-}
data F a
instance Foldable F where
foldMap _ t = case t of
-- or, = mempty
instance Traversable F where
traverse _ t = case t of
-- or, = pure $ case t of
instance Semigroup (F a) where
-- the only option
x <> _ = x
instance Monoid (F a) where
mempty = ????
Related
I'm currently learning Purescript by reading the Purescript by Example book (so far one of the only resources I've found that covers the language extensively).
I'm trying to implement the exercises in section 6.7 (Instance Dependencies), and I can't get my head around the following compiler error:
I've implemented the Semigroup and Eq instances for a data type data NonEmpty a = NonEmpty a (Array a) as follows:
instance eqNonEmpty :: Eq a => Eq (NonEmpty a) where
eq (NonEmpty h1 t1) (NonEmpty h2 t2) = h1 == h2 && t1 == t2
instance semigroupNonEmpty :: Semigroup (NonEmpty a) where
append (NonEmpty h1 t1) (NonEmpty h2 t2) = NonEmpty h1 (t1 <> [h2] <> t2)
But when I try to implement the Functor instance the same way I get the error above.
What seems to work is this:
instance functorNonEmpty :: Functor NonEmpty where
map f (NonEmpty h t) = NonEmpty (f h) (map f t)
Now, why is that? I can't figure it out.
Thanks!
That's just how the Functor class is defined: it applies to types that take a parameter. So, for example, the Functor class would apply to Maybe and to List, but wouldn't apply to Int or to String, and equally wouldn't apply to Maybe Int or List String.
The type NonEmpty does take a parameter, because that's how it is defined:
data NonEmpty a = ...
But a type NonEmpty a does not take a parameter, regardless of what a might be.
The classes Eq and Semigroup, on the other hand, expect a type without any parameters. So these classes can apply to Int, String, Maybe Boolean, and any other type without parameters, including NonEmpty a, regardless of what a might be.
In category theory, is the filter operation considered a morphism? If yes, what kind of morphism is it? Example (in Scala)
val myNums: Seq[Int] = Seq(-1, 3, -4, 2)
myNums.filter(_ > 0)
// Seq[Int] = List(3, 2) // result = subset, same type
myNums.filter(_ > -99)
// Seq[Int] = List(-1, 3, -4, 2) // result = identical than original
myNums.filter(_ > 99)
// Seq[Int] = List() // result = empty, same type
One interesting way of looking at this matter involves not picking filter as a primitive notion. There is a Haskell type class called Filterable which is aptly described as:
Like Functor, but it [includes] Maybe effects.
Formally, the class Filterable represents a functor from Kleisli Maybe to Hask.
The morphism mapping of the "functor from Kleisli Maybe to Hask" is captured by the mapMaybe method of the class, which is indeed a generalisation of the homonymous Data.Maybe function:
mapMaybe :: Filterable f => (a -> Maybe b) -> f a -> f b
The class laws are simply the appropriate functor laws (note that Just and (<=<) are, respectively, identity and composition in Kleisli Maybe):
mapMaybe Just = id
mapMaybe (g <=< f) = mapMaybe g . mapMaybe f
The class can also be expressed in terms of catMaybes...
catMaybes :: Filterable f => f (Maybe a) -> f a
... which is interdefinable with mapMaybe (cf. the analogous relationship between sequenceA and traverse)...
catMaybes = mapMaybe id
mapMaybe g = catMaybes . fmap g
... and amounts to a natural transformation between the Hask endofunctors Compose f Maybe and f.
What does all of that have to do with your question? Firstly, a functor is a morphism between categories, and a natural transformation is a morphism between functors. That being so, it is possible to talk of morphisms here in a sense that is less boring than the "morphisms in Hask" one. You won't necessarily want to do so, but in any case it is an existing vantage point.
Secondly, filter is, unsurprisingly, also a method of Filterable, its default definition being:
filter :: Filterable f => (a -> Bool) -> f a -> f a
filter p = mapMaybe $ \a -> if p a then Just a else Nothing
Or, to spell it using another cute combinator:
filter p = mapMaybe (ensure p)
That indirectly gives filter a place in this particular constellation of categorical notions.
To answer are question like this, I'd like to first understand what is the essence of filtering.
For instance, does it matter that the input is a list? Could you filter a tree? I don't see why not! You'd apply a predicate to each node of the tree and discard the ones that fail the test.
But what would be the shape of the result? Node deletion is not always defined or it's ambiguous. You could return a list. But why a list? Any data structure that supports appending would work. You also need an empty member of your data structure to start the appending process. So any unital magma would do. If you insist on associativity, you get a monoid. Looking back at the definition of filter, the result is a list, which is indeed a monoid. So we are on the right track.
So filter is just a special case of what's called Foldable: a data structure over which you can fold while accumulating the results in a monoid. In particular, you could use the predicate to either output a singleton list, if it's true; or an empty list (identity element), if it's false.
If you want a categorical answer, then a fold is an example of a catamorphism, an example of a morphism in the category of algebras. The (recursive) data structure you're folding over (a list, in the case of filter) is an initial algebra for some functor (the list functor, in this case), and your predicate is used to define an algebra for this functor.
In this answer, I will assume that you are talking about filter on Set (the situation seems messier for other datatypes).
Let's first fix what we are talking about. I will talk specifically about the following function (in Scala):
def filter[A](p: A => Boolean): Set[A] => Set[A] =
s => s filter p
When we write it down this way, we see clearly that it's a polymorphic function with type parameter A that maps predicates A => Boolean to functions that map Set[A] to other Set[A]. To make it a "morphism", we would have to find some categories first, in which this thing could be a "morphism". One might hope that it's natural transformation, and therefore a morphism in the category of endofunctors on the "default ambient category-esque structure" usually referred to as "Hask" (or "Scal"? "Scala"?). To show that it's natural, we would have to check that the following diagram commutes for every f: B => A:
- o f
Hom[A, Boolean] ---------------------> Hom[B, Boolean]
| |
| |
| |
| filter[A] | filter[B]
| |
V ??? V
Hom[Set[A], Set[A]] ---------------> Hom[Set[B], Set[B]]
however, here we fail immediately, because it's not clear what to even put on the horizontal arrow at the bottom, since the assignment A -> Hom[Set[A], Set[A]] doesn't even seem functorial (for the same reasons why A -> End[A] is not functorial, see here and also here).
The only "categorical" structure that I see here for a fixed type A is the following:
Predicates on A can be considered to be a partially ordered set with implication, that is p LEQ q if p implies q (i.e. either p(x) must be false, or q(x) must be true for all x: A).
Analogously, on functions Set[A] => Set[A], we can define a partial order with f LEQ g whenever for each set s: Set[A] it holds that f(s) is subset of g(s).
Then filter[A] would be monotonic, and therefore a functor between poset-categories. But that's somewhat boring.
Of course, for each fixed A, it (or rather its eta-expansion) is also just a function from A => Boolean to Set[A] => Set[A], so it's automatically a "morphism" in the "Hask-category". But that's even more boring.
filter can be written in terms of foldRight as:
filter p ys = foldRight(nil)( (x, xs) => if (p(x)) x::xs else xs ) ys
foldRight on lists is a map of T-algebras (where here T is the List datatype functor), so filter is a map of T-algebras.
The two algebras in question here are the initial list algebra
[nil, cons]: 1 + A x List(A) ----> List(A)
and, let's say the "filter" algebra,
[nil, f]: 1 + A x List(A) ----> List(A)
where f(x, xs) = if p(x) x::xs else xs.
Let's call filter(p, _) the unique map from the initial algebra to the filter algebra in this case (it is called fold in the general case). The fact that it is a map of algebras means that the following equations are satisfied:
filter(p, nil) = nil
filter(p, x::xs) = f(x, filter(p, xs))
I need to make a foldable instance for a Rose tree data structure:
data Rose a = a :> [Rose a]
deriving (Eq, Show)
With the following monoid and rose-related class/instances:
instance Functor Rose where
fmap f (a :> bs) = (f a) :> (map (fmap f) bs)
class Monoid a where
mempty :: a
(<>) :: a -> a -> a
instance Monoid [a] where
mempty = []
(<>) = (++)
What I tried:
instance Foldable Rose where
fold (a:>b) = a <> (foldMap fold b)
However this is not working properly, for the system check I get the error:
*** Failed! Exception: 'Prelude.undefined':
[] :> []
But I'm not sure why it doesn't work, could anyone help me out?
Thanks in advance!
Best Regards,
Skyfe.
Your implementation of fold was correct, there is no reason to change it.
The problem is that fold isn't sufficient to define Foldable. From the documentation:
class Foldable t where Source
Data structures that can be folded.
Minimal complete definition: foldMap or foldr.
So you must define either foldMap or foldr (or both). Defining foldMap is easier and more natural (and also more effective in many cases). So you should write something like:
import Data.Foldable
import Data.Monoid
data Rose a = a :> [Rose a]
deriving (Eq, Show)
instance Foldable Rose where
foldMap f (x :> xs) = f x <> foldMap (foldMap f) xs
This is only tangentially related, but if you realize that Rose Trees are the same as Cofree [] from Control.Comonad.Cofree, then you can get a Foldable instance "for free" from the foldable instance of [] like so:
import Control.Comonad.Cofree
import Data.Foldable as F
type RoseTree = Cofree []
Load it up into GHCi:
λ> let tree = 1 :< [1 :< [], 2 :< [], 3 :< []] :: RoseTree Int
λ> :t F.foldr (+) 0 tree
F.foldr (+) 0 tree :: Int
λ> F.foldr (+) 0 tree
7
You can also just derive Foldable, or write your own implementation (like you've done).
It seems like I found the answer to my own question.
Solution:
instance Foldable Rose where
fold (a:>b) = a <> (foldr (<>) mempty (map fold b))
Had to first append each of the elements in the list with the head element (and do the same for each of the bound elements to those rose trees), then fold the list together with an non-adjusting element mempty.
Although OP says he/she has found the answer, the solution lacks the base case:
instance Foldable Rose where
fold (a:>[]) = a <> mempty
fold (a:>b) = a <> (foldr (<>) mempty (map fold b))
Otherwise an expection about non-exhaustive patterns in function fold will be thrown.
Is there a standard specialization of Either in Haskell or Scala that makes the types contained in the Left and Right the same type?
In Haskell, I want something like this:
data SpecializedEither a = Left a | Right a
This might also be considered a slight generalization of Maybe that makes Nothing hold a value.
edit: Ganesh raises a very good point that a Monad instance can't be defined for this type. Is there a better way to do what I am trying to do?
There's a standard Monad instance on ((,) e) so long as e is a Monoid
instance Monoid e => Monad ((,) e) where
return a = (mempty, a)
(e1, a) >>= f = let (e2, b) = f a in (e1 <> e2, b)
Since Either a a and (Bool, a) are isomorphic (in two ways), we get a Monad instance as soon as we pick a Monoid for Bool. There are two (really four, see comments) such Monoids, the "and" type and the "or" type. Essentially, this choice ends up deciding as to whether the Left or Right side of your either is "default". If Right is default (and thus Left overrides it) then we get
data Either1 a = Left1 a | Right1 a
get1 :: Either1 a -> a
get1 (Left1 a) = a
get1 (Right1 a) = a
instance Monad Either1 where
return = Right1
x >>= f = case (x, f (get1 x)) of
(Right1 _, Right1 b) -> Right1 b
(Right1 _, Left1 b) -> Left1 b
(Left1 _, y ) -> Left1 (get1 y)
How about:
type Foo[T] = Either[T, T]
val x: Foo[String] = Right("")
// Foo[String] = Right()
In the process of writing a simple RPN calculator, I have the following type aliases:
type Stack = List[Double]
type Operation = Stack => Option[Stack]
... and I have written a curious-looking line of Scala code:
val newStack = operations.foldLeft(Option(stack)) { _ flatMap _ }
This takes an initial stack of values and applies a list of operations to that stack. Each operation may fail (i.e. yields an Option[Stack]) so I sequence them with flatMap. The thing that's somewhat unusual about this (in my mind) is that I'm folding over a list of monadic functions, rather than folding over a list of data.
I want to know if there's a standard function that captures this "fold-bind" behavior. When I'm trying to play the "Name That Combinator" game, Hoogle is usually my friend, so I tried the same mental exercise in Haskell:
foldl (>>=) (Just stack) operations
The types here are:
foldl :: (a -> b -> a) -> a -> [b] -> a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
So the type of my mystery foldl (>>=) combinator, after making the types of foldl and (>>=) line up, should be:
mysteryCombinator :: Monad m => m a -> [a -> m a] -> m a
... which is again what we'd expect. My problem is that searching Hoogle for a function with that type yields no results. I tried a couple other permutations that I thought might be reasonable: a -> [a -> m a] -> m a (i.e. starting with a non-monadic value), [a -> m a] -> m a -> m a (i.e. with arguments flipped), but no luck there either. So my question is, does anybody know a standard name for my mystery "fold-bind" combinator?
a -> m a is just a Kleisli arrow with the argument and result types both being a. Control.Monad.(>=>) composes two Kleisli arrows:
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
Think flip (.), but for Kleisli arrows instead of functions.
So we can split this combinator into two parts, the composition and the "application":
composeParts :: (Monad m) => [a -> m a] -> a -> m a
composeParts = foldr (>=>) return
mysteryCombinator :: (Monad m) => m a -> [a -> m a] -> m a
mysteryCombinator m fs = m >>= composeParts fs
Now, (>=>) and flip (.) are related in a deeper sense than just being analogous; both the function arrow, (->), and the data type wrapping a Kleisli arrow, Kleisli, are instances of Control.Category.Category. So if we were to import that module, we could in fact rewrite composeParts as:
composeParts :: (Category cat) => [cat a a] -> cat a a
composeParts = foldr (>>>) id
(>>>) (defined in Control.Category) is just a nicer way of writing as flip (.).
So, there's no standard name that I know of, but it's just a generalisation of composing a list of functions. There's an Endo a type in the standard library that wraps a -> a and has a Monoid instance where mempty is id and mappend is (.); we can generalise this to any Category:
newtype Endo cat a = Endo { appEndo :: cat a a }
instance (Category cat) => Monoid (Endo cat a) where
mempty = Endo id
mappend (Endo f) (Endo g) = Endo (f . g)
We can then implement composeParts as:
composeParts = appEndo . mconcat . map Endo . reverse
which is just mconcat . reverse with some wrapping. However, we can avoid the reverse, which is there because the instance uses (.) rather than (>>>), by using the Dual a Monoid, which just transforms a monoid into one with a flipped mappend:
composeParts :: (Category cat) => [cat a a] -> cat a a
composeParts = appEndo . getDual . mconcat . map (Dual . Endo)
This demonstrates that composeParts is a "well-defined pattern" in some sense :)
The one starting with a non-monadic value is (modulo flip)
Prelude> :t foldr (Control.Monad.>=>) return
foldr (Control.Monad.>=>) return
:: Monad m => [c -> m c] -> c -> m c
(or foldl)
(Yes, I know this doesn't answer the question, but the code layout in comments isn't satisfactory.)