I've been toying around in a Haskell for the past year or so and I'm actually starting to 'get' it, up until Monads, Lenses, Type Families, ... the lot.
I'm about to leave this comfort zone a little and I am moving to an OCaml project as a day job. Going through the syntax a little I was looking for similar higher level concepts, like for example functor.
I read the code in OCaml and the structure of a functor but I cannot seem to get whether they are now similar concepts in Haskell and OCaml or not.
In a nutshell, a functor in Haskell is for me mainly a way to lift functions in Haskell and I use it (and like it) like that.
In OCaml it gives me the feeling that it's closer to programming to an interface (for example when making a set or a list, with that compare function) and I wouldn't really know how to for example lift functions over the functor or so.
Can somebody explain me whether the two concepts are similar and if so what am I missing or not seeing? I googled around a bit and there doesn't seem to be a clear answer to be found.
Kasper
From a practical standpoint, you can think of "functors" in OCaml and Haskell as unrelated. As you said, in Haskell a functor is any type that allows you to map a function over it. In OCaml, a functor is a module parametrized by another module.
In Functional Programming, what is a functor? has a good description of what functors in the two languages are and how they differ.
However, as the name implies, there is actually a connection between the two seemingly disparate concepts! Both language's functors are just realizations of a concept from category theory.
Category theory is the study of categories, which are just arbitrary collections of objects with "morphisms" between them. The idea of a category is very abstract, so "objects" and "morphisms" can really be anything with a few restrictions—there has to be an identity morphism for every object and morphisms have to compose.
The most obvious example of a category is the category of sets and functions: the sets are the objects and the functions between sets the morphisms. Clearly, every set has has an identity function and functions can be composed. A very similar category can be formed by looking at a functional programming language like Haskell or OCaml: concrete types (e.g. types with kind *) are the objects and Haskell/OCaml functions are the morphisms between them.
In category theory, a functor is a transformation between categories. It is like a function between categories. When we're looking at the category of Haskell types, a functor is essentially a type-level function: it maps types to something else. The particular kind of functor we care about maps types to other types. A perfect example of this is Maybe: Maybe maps Int to Maybe Int, String to Maybe String and so on. It provides a mapping for every possible Haskell type.
Functors have one additional requirement—they have to map the category's morphisms as well as the objects. In particular, if we have a morphism A → B and our functor maps A to A' and B to B', it has to map the morphism A → B to some morphism A' → B'. As a concrete example, let's say we have the types Int and String. There are a whole bunch of Haskell functions Int → String. For Maybe to be a proper functor, it has to have a function Maybe Int → Maybe String for each of these.
Happily, this is exactly what the fmap function does—it maps functions. For Maybe, it has the type (a → b) → Maybe a → Maybe b; we can add some parentheses to get: (a → b) → (Maybe a → Maybe b). What this type signature tells us is that for any normal function we have, we also have a corresponding function over Maybes.
So a functor is a mapping between types that also preserves the functions between them. The fmap function is essentially just a proof of this second restriction on functors. This makes it easy to see how the Haskell Functor class is just a particular version of the mathematical concept.
So what about OCaml? In OCaml, a functor is not a type—it's a module. In particular, it's a parametrized module: a module that takes another module as an argument. Already, we can see some parallels: in Haskell, a Functor is like a type-level function; in OCaml, a functor is like a module-level function. So really, it's the same mathematical idea; however, instead of being used on types—like in Haskell—it's used on modules.
There's far more detail about how OCaml functors related to category theory functors on the CS site: What is the relation between functors in SML and Category theory?. The question talks about SML rather than OCaml per se, but my understanding is that the module system of OCaml is very closely related to that of SML.
In summary: functors in Haskell and in OCaml are two fundamentally different structures which both happen to be reifications of the same very abstract mathematical idea. I think it's pretty neat :).
Related
Hask is usually thought to be the category whose objects are types and morphisms are functions.
However, I've seen Conor McBride (#pigworker) warn against the use of Hask multiple times (1, 2, 3):
I would discourage talk of "the Hask Category" because it subconsciously conditions you against looking for other categorical structure in Haskell programming.
Note, I dislike the use of "Hask" as the name of the "category of Haskell types and functions": I fear that labelling one category as the Haskell category has the unfortunate side-effect of blinding us to the wealth of other categorical structure in Haskell programming. It's a trap.
I wish people wouldn't call it "Hask", though: it threatens to limit the imagination.
What other categories can we see in Haskell?
In one of his answers, he touches upon some of these ideas, but I wonder if someone could expand upon it; and I wonder if there are even more examples.
[...] there's a ton of categorical structure lurking everywhere, there's certainly a ton of categorical structure available (possibly but not necessarily) at higher kinds. I'm particularly fond of functors between indexed families of sets.
Constraints in Haskell also form a category. The objects are the constraints, and the arrows mean "this constraint implies this other constraint". So every constraint implies itself, and there's an arrow between Monad f and Applicative f, between Ord a and Eq a and between Ord a and Ord [a].
It is a thin category, so there is at most one arrow between two objects.
Gabriel Gonzalez has blogged about this. Here's one such post:
http://www.haskellforall.com/2012/08/the-category-design-pattern.html
In it, he calls Hask "the function category", and also discusses "the Kleisli category" and "the pipes category." These are all examples of instances of the Category typeclass in Haskell. The Category typeclass in Haskell is a subset of the categories you can find in Haskell.
I once uploaded an educational package that demonstrates one example of this. I called it MHask.
http://hackage.haskell.org/package/MHask
Copied from the hackage page:
MHask is the category where
The objects are Haskell types of kind (* → *) that have an instance of Prelude.Monad
An arrow from object m to object n is a Haskell function of the form (forall x. m x → n x)
Arrow composition is merely a specialization of Haskell function composition
The identity arrow for the object m is the Prelude.id function in Haskell, specialized to (forall x. m x → m x)
Caveat emptor; I have not looked at this in a long time. There may be mistakes.
I read an article which said:
Providing instances for the many standard type-classes [Functors] will immediately give you a lot of functionality for practically free
My question is: what is this functionality that you get for free (for functors or other type-classes)? I know what the definition of a functor is, but what do I get for free by defining something as a functor/other type-class. Something other than a prettier syntax. Ideally this would be general and useful functions that operate on functors/other type-classes.
My imagination (could be wrong) of what free means is functions of this sort: TypeClass x => useful x y = ..
== Edit/Additition ==
I guess I'm mainly asking about the more abstract (and brain boggling) type-classes, like the ones in this image. For less abstract classes like Ord, my object oriented intuition understands.
Functors are simple and probably not the best example. Let's look at Monads instead:
liftM - if something is a Monad, it is also a Functor where liftM is fmap.
>=>, <=<: you can compose a -> m b functions for free where m is your monad.
foldM, mapM, filterM... you get a bunch of utility functions that generalize existing functions to use your monad.
when, guard* and unless -- you also get some control functions for free.
join -- this is actually fairly fundamental to the definition of a monad, but you don't need to define it in Haskell since you've defined >>=.
transformers -- ErrorT and stuff. You can bolt error handling onto your new type, for free (give or take)!
Basically, you get a wide variety of standard functions "lifted" to use your new type as soon as you make it a Monad instance. It also becomes trivial (but alas not automatic) to make it a Functor and Applicative as well.
However, these are all "symptoms" of a more general idea. You can write interesting, nontrivial code that applies to all monads. You might find some of the functions you wrote for your type--which are useful in your particular case, for whatever reason--can be generalized to all monads. Now you can suddenly take your function and use it on parsers, and lists, and maybes and...
* As Daniel Fischer helpfully pointed out, guard requires MonadPlus rather than Monad.
Functors are not very interesting by themselves, but they are a necessary stepping stone to get into applicative functors and Traversables.
The main property which makes applicative functors useful is that you can use fmap with the applicative operator <*> to "lift" any function of any arity to work with applicative values. I.e. you can turn any a -> b -> c -> d into Applicative f => f a -> f b -> f c -> f d. You can also take a look at Data.Traversable and Data.Foldable which contain several general purpose functions that involve applicative functors.
Alternative is a specialized applicative functor which supports choice between alternatives that can "fail" (the exact meaning of "empty" depends in the applicative instance). Applicative parsers are one practical example where the definitions of some and many are very intuitive (e.g. match some pattern zero-or-more times or one-or-more times).
Monads are one of the most interesting and useful type-classes, but they are already well covered by the other answers.
Monoid is another type-class that is both simple and immediately useful. It basically defines a way to add two pieces of data together, which then gives you a generic concat as well as functionality in the aforementioned Foldable module and it also enables you to use the Writer monad with the data type.
There are many of the standard functions in haskell that require that their arguments implement one or more type-classes. Doing so in your code allows other developers (or yourself) to use your data in ways they are already familiar with, without having to write additional functions.
As an example, implementing the Ord type-class will allow you to use things like sort, min, max, etc. Where otherwise, you would need sortBy and the like.
Yes, it means that implementing the type class Foo gives you all the other functions that have a Foo constraint "for free".
The Functor type class isn't too interesting in that regard, as it doesn't give you a lot.
A better example is monads and the functions in the Control.Monad module. Once you've defined the two Monad functions (>>=) and return for your type, you get another thirty or so functions that can then be used on your type.
Some of the more useful ones include: mapM, sequence, forever, join, foldM, filterM, replicateM, when, unless and liftM. These show up all the time in Haskell code.
As others have said, Functor itself doesn't actually get you much for free. Basically, the more high-level or general a typeclass is (meaning the more things fit that description), then the less "free" functionality you are going to get. So for example, Functor, and Monoid don't provide you with much, but Monad and Arrow provide you with a lot of useful functions for free.
In Haskell, it's still a good idea to write an instance for Functor and Monoid though (if your data type is indeed a functor or a monoid), because we almost always try to use the most general interface possible when writing functions. If you are writing a new function that can get away with only using fmap to operate on your data type, then there is no reason to artificially restrict that function to to Monads or Applicatives, since it might be useful later for other things.
Your object-oriented intuition carries across, if you read "interface and implementation" for "typeclass and instance". If you make your new type C an instance of a standard typeclass B, then you get for free that your type will work with all existing code A that depends on B.
As others have said, when the typeclass is something like Monad, then the freebies are the many library functions like foldM and when.
Every time someone promises to "explain monads", my interest is piqued, only to be replaced by frustration when the alleged "explanation" is a long list of examples terminated by some off-hand remark that the "mathematical theory" behind the "esoteric ideas" is "too complicated to explain at this point".
Now I'm asking for the opposite. I have a solid grasp on category theory and I'm not afraid of diagram chasing, Yoneda's lemma or derived functors (and indeed on monads and adjunctions in the categorical sense).
Could someone give me a clear and concise definition of what a monad is in functional programming? The fewer examples the better: sometimes one clear concept says more than a hundred timid examples. Haskell would do nicely as a language for demonstration though I'm not picky.
This question has some good answers: Monads as adjunctions
More to the point, Derek Elkins' "Calculating Monads with Category Theory" article in TMR #13 should have the sort of constructions you're looking for: http://www.haskell.org/wikiupload/8/85/TMR-Issue13.pdf
Finally, and perhaps this is really the closest to what you're looking for, you can go straight to the source and look at Moggi's seminal papers on the topic from 1988-91: http://www.disi.unige.it/person/MoggiE/publications.html
See in particular "Notions of computation and monads".
My own I'm sure too condensed/imprecise take:
Begin with a category Hask whose objects are Haskell types, and whose morphisms are functions. Functions are also objects in Hask, as are products. So Hask is Cartesian closed. Now introduce an arrow mapping every object in Hask to MHask which is a subset of the objects in Hask. Unit!
Next introduce an arrow mapping every arrow on Hask to an arrow on MHask. This gives us map, and makes MHask a covariant endofunctor. Now introduce an arrow mapping every object in MHask which is generated from an object in MHask (via unit) to the object in MHask which generates it. Join! And from the that, MHask is a monad (and a monoidal endofunctor to be more precise).
I'm sure there is a reason why the above is deficient, which is why I'd really direct you, if you're looking for formalism, to the Moggi papers in particular.
As a compliment to Carl's answer, a Monad in Haskell is (theoretically) this:
class Monad m where
join :: m (m a) -> m a
return :: a -> m a
fmap :: (a -> b) -> m a -> m b
Note that "bind" (>>=) can be defined as
x >>= f = join (fmap f x)
According to the Haskell Wiki
A monad in a category C is a triple (F : C → C, η : Id → F, μ : F ∘ F → F)
...with some axioms. For Haskell, fmap, return, and join line up with F, η, and μ, respectively. (fmap in Haskell defines a Functor). If I'm not mistaken, Scala calls these map, pure, and join respectively. (Scala calls bind "flatMap")
Ok, using Haskell terminology and examples...
A monad, in functional programming, is a composition pattern for data types with the kind * -> *.
class Monad (m :: * -> *) where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
(There's more to the class than that in Haskell, but those are the important parts.)
A data type is a monad if it can implement that interface while satisfying three conditions in the implementation. These are the "monad laws", and I'll leave it to those long-winded explanations for the full explanation. I summarize the laws as "(>>= return) is an identity function, and (>>=) is associative." It's really not more than that, even if it can be expressed more precisely.
And that's all a monad is. If you can implement that interface while preserving those behavioral properties, you have a monad.
That explanation is probably shorter than you expected. That's because the monad interface really is very abstract. The incredible level of abstraction is part of why so many different things can be modeled as monads.
What's less obvious is that as abstract as the interface is, it allows generically modeling any control-flow pattern, regardless of the actual monad implementation. This is why the Control.Monad package in GHC's base library has combinators like when, forever, etc. And this is why the ability to explicitly abstract over any monad implementation is powerful, especially with support from a type system.
You should read the paper by Eugenio Moggi "Notions of computations and monads" which explain the then proposed role of monads to structure denotational semantic of effectful languages.
Also there is a related question:
References for learning the theory behind pure functional languages such as Haskell?
As you don't want hand-waving, you have to read scientific papers, not forum answers or tutorials.
A monad is a monoid in the category of endofunctors, whats the problem?.
Humor aside, I personally believe that monads, as they are used in Haskell and functional programming, are better understood from the monads-as-an-interface point of view (as in Carl's and Dan's answers) instead of from the monads-as-the-term-from-category-theory point of view. I have to confess that I only really internalized the whole monad thing when I had to use a monadic library from another language in a real project.
You mention that you didn't like all the "lots of examples" tutorials. Has anyone ever pointed you to the Awkward squad paper? It focuses manly in the IO monad but the introduction gives a good technical and historical explanation of why the monad concept was embraced by Haskell in the first place.
I don't really know what I'm talking about, but here's my take:
Monads are used to represent computations. You can think of a normal procedural program, which is basically a list of statements, as a bunch of composed computations. Monads are a generalization of this concept, allowing you to define how the statements get composed. Each computation has a value (it could just be ()); the monad just determines how the value strung through a series of computations behaves.
Do notation is really what makes this clear: it's basically a special sort of statement-based language that lets you define what happens between statements. It's as if you could define how ";" worked in C-like languages.
In this light all of the monads I've used so far makes sense: State doesn't affect the value but updates a second value which is passed along from computation to computation in the background; Maybe short-circuits the value if it ever encounters a Nothing; List lets you have a variable number of values passed through; IO lets you have impure values passed through in a safe way. The more specialized monads I've used like Gen and Parsec parsers are also similar.
Hopefully this is a clear explanation which isn't completely off-base.
Since you understand monads in the category-theoretic sense I am interpreting your question as being about the presentation of monads in functional programming.
Thus my answer avoids any explanation of what a monad is, or any intuition about its meaning or use.
Answer: In Haskell a monad is presented, in an internal language for some category, as the (internalised) maps of a Kleisli triple.
Explanation:
It is hard to be precise about the properties of the "Hask category", and these properties are largely irrelevant for understanding Haskell's presentation of monads.
Instead, for this discussion, it is more useful to understand Haskell as an internal language for some category C. Haskell functions define morphisms in C and Haskell types are objects in C, but the particular category in which these definitions are made is unimportant.
Parameteric data types, e.g. data F a = ..., are object mappings, e.g. F : |C| -> |C|.
The usual description of a monad in Haskell is in Kleisli triple (or Kleisli extension) form:
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
where:
m is the object mapping m :|C| -> |C|
return is the unit operation on objects
>>= (pronounced "bind" by Haskellers) is the extension operation on morphisms but with its first two parameters swapped (cf. usual signature of extension (-)* : (a -> m b) -> m a -> m b)
(These maps are themselves internalised as families of morphisms in C, which is possible since m :|C| -> |C|).
Haskell's do-notation (if you have come across this) is therefore an internal language for Kleisli categories.
The Haskell wikibook page has a good basic explanation.
I am confused about using Functor
is Functor used for defining properties of mapping and how to write a mapping's properties in Haskell?
if so, can haskell be used to generate function or other things after definition written
Malformed head of type or class declaration: flow x y
import Control.Applicative
class flow x y where { f :: x y -> x; } // this line i do not know whether is enforced to write
// how to write this map
instance flow Int Int where
flow t flow(s, p) = flow(t+s, p)
flow 0 p = p
if there are more runnable example rather than the definition of the haskell, it would be better
when i replace properties in example found in google, usually can not run, or fragments
when use example about mapping, for example A -> B, there are data A data B defined first, but do not know why use data as a type defined, when i read category theory, there are arrows and objects
both are Hom, Functor is from Hom to Hom, does it mean data represent Hom?
When compare with software Singular, i become more confusing. Hom is a operation of kontraHom and Kohom and take two matrix.
Do Hom have different meaning in Haskell and Singular
Singular is a computer algebra system. Haskell is a programming language which computer algebra can be implemented within. You need to start simply and just learn basic Haskell syntax and concepts before trying to see the categorical/algebriac picture, especially since different elements can be implemented in different ways.
But let's try something simple to establish a common language. The notes I give here should be consistent with the treatment here: http://en.wikibooks.org/wiki/Haskell/Category_theory
One approach is to describe the category Hask. The objects of Hask are all Haskell types. Hask contains function types, as well as pairs, so it is cartesian closed, and all its arrows are isomorphic to objects. In categorical terms, a hom-set is the collection of all morphisms between two objects. So the hom-set on (Int,Float) is the collection of all functions that turn an Int into a Float.
Categorically, a functor between categories X and Y sends the objects of X to Y and the arrows of X to Y. It also therefore sends the hom-sets (collections of arrows) of X to Y.
The class Functor in Haskell provides part of what you get with a categorical functor. It provides an operation fmap that sends arrows on objects in Hask to arrows on some other category (which, in our case, must also be composed of some objects from Hask). It can send functions on values to functions on lists of values, or functions on values to functions on pairs which contain values, etc.
All that said, I would recommend learning Haskell without thinking about writing type classes or instances at all for some time. Stick to explicit data declarations and functions until you're more comfortable with the basic features of the language.
As an attempt at addressing the immediate confusion, a Haskell Functor defines a structure you can 'map' over, by specifying an implementation of 'fmap' (so yes, in Haskell you could use an instance of the Functor type class in order to specify an implementation of fmap for your specific structure)
Your provided code is problematic in two ways: i) A functor is already provided by Haskell (no need to redefine the class; instead you want to define an 'instance' of the Functor class), and ii) you need to adhere to the Functor interface.
Though I may suggest a more comprehensive resource (highly recommended is the book "Real World Haskell"), if you absolutely need to know more about how to deal with Haskell's instantiation of Functors, an excellent article is http://www.haskell.org/haskellwiki/Monads_as_containers
(every Monad is a Functor).
In the question, Seeking constructive criticism on monad implementation, abesto asked people to criticize his "Monad" which kept count of the number of bind operations. It turned out that this was not actually a monad because it did not satisfy the first two monadic laws, but I found the example interesting. Is there any data type that would be suitable for such kinds of structures?
That's an interesting question, and has to do with the mathematical lineage of monads.
We could certainly create a typeclass called something like Monadish, which would look exactly like the Monad typeclass:
class Monadish m where
returnish :: a -> m a
bindish :: m a -> (a -> m b) -> m b
So the monad laws have nothing to do with the actual signature of the typeclass; they're extra information that an implementor has to enforce by themselves. So, in one sense, the answer is "of course"; just make another typeclass and say it doesn't have to satisfy any laws.
But is such a typeclass interesting? For a mathematician, the answer would be no: the lack of any laws means that there is no interesting structure by which to reason with. When we define a mathematical structure, we usually define some objects (check), some operations (check) and then some properties of the operations (...nope). We need all three of these to prove theorems about this class of objects, and, to take one example, abstract algebra is all about taking the same operations and adding more or fewer laws.
For a software engineer, the answer is a little more complex. Reasoning is not required: you can always just use a typeclass to overload syntax for your own nefarious purposes. We can use a typeclass to group things together that "feel" the same, even though we don't have any formal reasons for believing so. There are some benefits to doing this, but I personally feel this throws out a lot of the benefits of having laws, and leads to architecture astronauts who invent abstract structures without a whole lot of thought of their applicability. Maths is a safer bet: the monad laws correspond to left identity, right identity, and associativity, reasonably fundamental assumptions that even a non-mathematical person would be familiar with.