Is there a term for a monad that is also a comonad? - haskell

I'm just wondering whether there's a concise term for something that's both a monad and a comonad. I've done some searching, and I know these structures exist, but I haven't found a name for them.

Such a creature, subject to certain conditions, is sometimes called a "Hopf monad" or a "Bimonad" (http://ncatlab.org/nlab/show/Hopf+monad).
However, this also requires fulfilling a number of axioms regarding distributive properties, and I haven't seen it come up in a programming context in any particular way.

As far as I know, there is no term to define it because a monad-comonad would enforce nothing: you can always do a return to get in or an extract to get out.
As types are there to enforce some constraints, a too permissive constraint wouldn't be of any use. As no one would use it (except for the identity), no one probably bothered to name it.

Related

Haskell: use or uses in Getter

In Control.Lens we have Getter that can access the nested structure. Getter has use and uses, but it's not clear to me how they work. So it'd be great if someone can provide some simple examples that use or uses is utilised.
Why do I need to know it? because I'm reading some implementation in Haskell and "uses" and "use" were used in them. In particualr it says:
inRange <- uses fsCurrentCoinRangeUpperBound (coinIndex <=)
If the above code is just for comparing (<=) two values, then why do we need "uses" at all, there?
As I tried to make clear in my answer to your other question over at Use cases of makePrisms with examples there is a lot of requisite knowledge required before you can understand this.
First up, you have to understand Lens quite well. Judging from your other question you're just beginning them. This is great! They're amazingly cool and it's excellent to tackle such things.
However, I'd give you a big amount of caution here, one of the dangers of Haskell is it's so powerful, and can be so expressive and terse, that it seems easy to try to skip stuff.
If you skipped understanding algebraic data types very well, for example, you can easily read code and think you have an understanding of it when you don't at all. This can then lead to compounded confusion, and you'll feel like you don't understand any of it, which actually might be true, but that feeling is not a good feeling to have when learning Haskell.
I don't want you to feel like that.
So I encourage you to learn Lens, but if you don't have the requisite knowledge for Lens, then I encourage you to go get that first. It's not too hard to understand this stuff to a degree, but the way Lens is written is not trivial or easy to approach for programmers who aren't quite familiar with at least simple types, parameterized types, Algebraic Data Types, Typeclasses, the Functor typeclass, and to really understand it, you need to understand several instances of Functor.
As well, if you're trying to understand use and uses, which only make sense when dealing with State values, then I'd suggest it's almost impossible to understand what's happening without knowing what State is, as well as what Lens does and is.
use and uses are for taking a lens and a state value and looking into the current state inside a State value. So, to a degree you really need to also understand what do syntax is doing, therefore the Monad typeclass to a degree, as well as how the State / MonadState work from that perspective.
If any of these preliminaries are skipped, you'll be confused.
I hope this helps! And I wish you well.

What's the current status of restricted monads?

Going back to at least the late 1990s there have been people wishing for the integration of restricted monads into Haskell in a friendly way.
For example, without restricted monads you can't make an efficient monad out of Set, Map or probability distributions. Here's a SO question from a few years ago where someone else ran afoul of this problem.
There are various workarounds that people have come up with, including:
Creating a new type class for every possible restriction.
Using Template Haskell.
Using Constraint Kinds.
None of these approaches seem to be "canonical" however. I found a comment from Don Stewart on this blog post, in 2007, where he intimated that we were "quite close" to having restricted monads with Indexed types.
What is the current status? Is there now a 'canonical' way to do restricted monads? Or we are still living with workarounds?
There's a recent paper by Anders Persson, Emil Axelsson, and Josef Svenningson that shows a way to encode restricted monads. I've forgotten the details, but I remember it was a nice paper.
Persson, A. ; Axelsson, E. ; Svenningsson, J. (2011). Generic monadic constructs for embedded languages. IFL 2011, the 23rd Symposium on Implementation and Application of Functional Languages.
Actually it is possible to obtain an efficient Set monad as a regular monad,
without any restrictions. In two distinct ways. The following article
explains both:
http://okmij.org/ftp/Haskell/set-monad.html
The article also points out that restricted monads are actually quite
restricted and preclude many monadic idioms. I conjecture that the
implementation methods are general and any restricted monad can be
turned into the usual one, without losing efficiency. So, it may seem
that we don't need restricted monads at all.

What happens to you if you break the monad laws?

Do the compiler or the more "native" parts of the libraries (IO or functions that have access to black magic and the implementation) make assumptions about these laws? Will breaking them cause the impossible to happen?
Or do they just express a programming pattern -- ie, the only person you'll annoy by breaking them are people who use your code and didn't expect you to be so careless?
The monad laws are simply additional rules that instances are expected to follow, beyond what can be expressed in the type system. Insofar as Monad expresses a programming pattern, the laws are part of that pattern. Such laws apply to other type classes as well: Monoid has very similar rules to Monad, and it's generally expected that instances of Eq will follow the rules expected for an equality relation, among other examples.
Because these laws are in some sense "part of" the type class, it should be reasonable for other code to expect they will hold, and act accordingly. Misbehaving instances may thus violate assumptions made by client code's logic, resulting in bugs, the blame for which is properly placed at the instance, not the code using it.
In short, "breaking the monad laws" should generally be read as "writing buggy code".
I'll illustrate this point with an example involving another type class, modified from one given by Daniel Fischer on the haskell-cafe mailing list. It is (hopefully) well known that the standard libraries include some misbehaving instances, namely Eq and Ord for floating point types. The misbehavior occurs, as you might guess, when NaN is involved. Consider the following data structure:
> let x = fromList [0, -1, 0/0, -5, -6, -3] :: Set Float
Where 0/0 produces a NaN, which violates the assumptions about Ord instances made by Data.Set.Set. Does this Set contain 0?
> member 0 x
True
Yes, of course it does, it's right there in plain sight! Now, we insert a value into the Set:
> let x' = insert (0/0) x
This Set still contains 0, right? We didn't remove anything, after all.
> member 0 x'
False
...oh. Oh, dear.
The compiler doesn't make any assumptions about the laws, however, if your instance does not obey the laws, it will not behave like a monad -- it will do strange things and otherwise appear to your users to not work correctly (e.g. dropping values, or evaluating things in the wrong order).
Also, refactorings your users might make assuming the monad laws hold will obviously not be sound.
For people working in more "mainstream" languages, this would be like implementing an interface, but doing so incorrectly. For example, imagine you're using a framework that offers an IShape interface, and you implement it. However, your implementation of the draw() method doesn't draw at all, but instead merely instantiates 1000 more instances of your class.
The framework would try to use your IShape and do reasonable things with it, and God knows what would happen. It'd be kind of an interesting train wreck to watch.
If you say you're a Monad, you're "declaring" that you adhere to its contract and laws. Other code will believe your declaration and act accordingly. Since you lied, things will go wrong in unforeseen ways.

Problems in Haskell's Type-System

Ive come across some answers (here in SO) saying that Haskell has many "dark corners" in its type system, and also some messy holes. Could someone elaborate on this?
Thanks in advance
I guess I should answer this, especially since two people so far have misinterpreted my remarks...
Regarding non-termination, the remark in question was slight hyperbole for dramatic effect, and referred to non-termination at the value level. This was in context of comparing Haskell to theorem provers, in an answer to someone who mentioned type-enforced correctness properties as something they particularly appreciated. In that sense, the presence of ⊥ inhabiting otherwise empty types is a "flaw", because it changes the meaning of a type like A -> B from "given an A, produces a B" into "given an A, either produces a B or crashes the program" which is, for obvious reasons, somewhat less satisfying from a proof-of-correctness standpoint.
It's also completely irrelevant to almost all day-to-day programming and no worse than any other general-purpose language because, of course, the possibility of non-termination is required for Turing-completeness.
I don't have any problem with UndecidableInstances. Actually, it bothers me less than ⊥ at the value level does because it only crashes GHC when compiling, not the finished program. OverlappingInstances is another matter, though, and the ad hoc mishmash of GHC extensions to provide little bits of things that would most naturally require dependent types certainly qualifies as "messy".
But keep in mind that most of the things I'm complaining about in Haskell are only a problem because of the otherwise very solid foundation. Most type systems in other statically typed languages aren't even coherent enough to be called "wrong" in comparison, and cleaning up the stuff I'm calling "messy" is an active and ongoing area of research.
Haskell's type system has no problems or messy holes, actually. Haskell 98 can be fully type-inferred. It possesses what is known as the "principal type" property, which is to say that any given expression has at most a single most general type. There are, however, a range of expressions which are good and useful and valid but do not type under Haskell 98. Most important of these are higher-ranked types. forall a b. (a -> b) -> a -> b is an (uninteresting) example of a rank-one type, which is to say that the forall is only at the very outside. forall b. -> (forall a. a -> a) -> b -> b is an example of a useless but possible type which is not rank-one, and cannot be expressed in Haskell98. Higher ranked types are one of many things which break the principal type property.
As one adds more and more extensions to the basic Haskell98 system, there begin to be tradeoffs introduced between the ability to write really powerful types which express both different types of polymorphism and different types of constraints and the ability to have as much code as possible completely type-inferred. At the very edges of what's possible, types can get messy and complicated, and occasionally you can run into things that seem like they should work but don't. But at that point, you're generally doing what's known as "type-level programming" where a great deal of your application logic has been embedded in the types themselves, and through a combination of typeclass tricks you've conned the compiler into, essentially, running the types as a program at compile time.
I disagree, by the way, with camccann's assertion that potential nontermination is a messy compromise in the type-checker. I think it's a perfectly useful feature, in fact a prerequisite for turning-completeness at the type level, and you only risk it if you explicitly ask the compiler to start allowing lots of dodgy stuff.
So you're referring to Camccann saying "Haskell's type system is full of holes, due to nontermination and other messy compromises"? I think he's talking about the UndecidableInstances extension and probably a few others.
Then you referred to Norman, I can only assume, saying "Haskell's type system is ambitious and powerful, but it is continually being improved, which means there is some inconsistency as a result of history.". I'm sure he had something in mind but will let him clarify when he see`s this question.

Haskell data types usage good practicies

Reading "Real world Haskell" i found some intresting question about data types:
This pattern matching and positional
data access make it look like you have
very tight coupling between data and
code that operates on it (try adding
something to Book, or worse change the
type of an existing part).
This is usually a very bad thing in
imperative (particularly OO)
languages... is it not seen as a
problem in Haskell?
source at RWH comments
And really, writing some Haskell programs I found that when I make small change to data type structure it affects almost all functions that use that data type. Maybe there are some good practices for data type usage. How can i minimize code coupling?
What you are describing is commonly known as the expression problem -- http://en.wikipedia.org/wiki/Expression_Problem.
There is a definite trade-off to be made, haskell code in general, and algebraic data types in particular, tends to fall into the hard to change the type but easy to add functions over the type. This optimizes for (up front) well-designed, complete, data types.
All that said, there are a number of things that you can do to reduce the coupling.
Define good library functions, by defining a complete set of combinators and higher order functions that are useful for interacting with your data type you will reduce coupling. It is often said that when ever you think of pattern matching there is a better solution using higher-order functions. If you look for these situations you will be in a better spot.
Expose your data structures as more abstract types. This means implementing all appropriate type classes. This will assist with defining a library functions as you will get a bunch for free with any of the type classes you implement, for examples look at operations over Functor or Monad.
Hide (as much as possible) any type constructors. Constructors expose implementation detail and will encourage coupling. Hint: this links in with defining a good api for interacting with your type, consumers of your type should rarely, if ever, have to use the type constructors.
The haskell community seems particularly good at this, if you look at many of the libraries on hackage you will find really good examples of implementing type classes and exposing good library functions.
In addition to what's been said:
One interesting approach is the "scrap your boilerplate" style of defining functions over data types, which makes use of generic functions (as opposed to explicit pattern matching) to define functions over the constructors of a data type. Looking at the "scrap your boilerplate" papers, you will see examples of functions which can cope with changes to the structure of a data type.
A second method, as Hibberd pointed out, is to use folds, maps, unfolds, and other recursion combinators, to define your functions. When you write functions using higher order functions, oftentimes small changes to the underlying data type can be dealt with in the instance declarations for Functor, Foldable, and so on.
First, I'd like to mention that in my view, there are two kinds of couplings:
One that makes your code cease to compile when you change one and forget to change the other
One that makes your code buggy when you change one and forget to change the other
While both are problematic, the former is significantly less of a headache, and that seems to be the one you're talking about.
I think the main problem you're mentioning is due to over-using positional arguments. Haskell almost forces you to have positional arguments in your ordinary functions, but you can avoid them in your type products (records).
Just use records instead of multiple anonymous fields inside data constructors, and then you can pattern-match any field you want out of it, by name.
bad (Blah _ y) = ...
good (Blah{y = y}) = ...
Avoid over-using tuples, especially those beyond 2-tuples, and liberally create records/newtypes around things to avoid positional meaning.

Resources