tag:blogger.com,1999:blog-1777990983847811806.post5024695655492896461..comments2024-03-16T16:29:29.582-07:00Comments on Haskell for all: DefaultsGabriella Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comBlogger18125tag:blogger.com,1999:blog-1777990983847811806.post-18826822592036935402023-01-09T07:33:07.090-08:002023-01-09T07:33:07.090-08:00Forgive me if I'm mistaken, but I believe libe...Forgive me if I'm mistaken, but I believe libeako's point was a bit different. The class `Traversable` can be imagined as:<br /><br />data TraversableD t = TD<br /> { traverse :: forall f a b. Applicative f => (a -> f b) -> t a -> f (t b)<br /> , ...<br /> , proofOfLaws :: ....}<br /><br />An instance of Traversable can then be thought of as an instance of Default:<br /><br />instance Default (TraversableD []) where<br /> def = T {...}<br /><br />There's nothing really special about the left to right traversal order.David Feuerhttps://www.blogger.com/profile/09876399378889159844noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-26585722255249981692020-08-13T08:10:46.397-07:002020-08-13T08:10:46.397-07:00You're welcome! :)You're welcome! :)Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-88817629604101692192020-08-13T06:25:36.015-07:002020-08-13T06:25:36.015-07:00Thank you very much! :-)Thank you very much! :-)Qqwyhttps://www.blogger.com/profile/08742464027743784085noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-46342520974039282822020-08-12T19:41:55.988-07:002020-08-12T19:41:55.988-07:00This StackOverflow question and answer summarize m...This StackOverflow question and answer summarize my view on this: https://stackoverflow.com/a/17100055<br /><br />For the example you cite, you could supply the starting state as an ordinary function argument and you don't benefit from the alternative approach using a Default typeclass. Quite the opposite: the global coherence constraint that typeclasses require works against you because if somebody supplies the wrong `Default` instance for a type you are out of luck.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-28808912770700879472020-08-12T11:33:07.568-07:002020-08-12T11:33:07.568-07:00Thank you for your response!
I'm not entirely ...Thank you for your response!<br />I'm not entirely convinced yet. <br />Say we have a state machine called `Counter`. I'd represent its state as e.g. `newtype Counter = Counter {getCount :: Int}`, with `initial` being defined as `Counter 0`. <br /><br />There is no dispatching to the `Default` instance for `Int` (which, as you pointed out, would be ambiguous because we could pick the additive identity, multiplicative identity, etc) but this is not needed for the abstraction of a `Default` typeclass to be useful.<br /><br />Semigroup provides `<>` (i.e. `mappend`) for Monoid. But why is there no typeclass for structures that only provide the other half (i.e. only `mempty`)? This would allow functions like `fromMaybeDefault :: Default a => Maybe a -> a` to be written.<br /><br />I believe there are more than enough types for which a single well-defined identity value exists even though there is no associated binary operation. I also believe that there types for which multiple arbitrary identity values are possible but it does not matter which one we pick specifically.<br /><br />What do you think?Qqwyhttps://www.blogger.com/profile/08742464027743784085noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-89052495687647824482020-08-09T15:54:41.589-07:002020-08-09T15:54:41.589-07:00I think the point from the post still holds in tha...I think the point from the post still holds in that scenario. For example, if the state machine's internal state is an Int, then how would you know whether to select 0 or 1 as the initial state?Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-42931634219346319672020-08-09T13:13:08.203-07:002020-08-09T13:13:08.203-07:00What about types that behave like state machines? ...What about types that behave like state machines? To clarify: I am talking about any datastructure whose internals are potentially hidden, and whose external interface provides (a) an 'initial' or 'new' function and (b) functions that take the structure as input and return an updated structure as output.<br /><br />In some cases, the 'initial' function will have some parameters but in many cases it will not. It might make sense to standardize the naming of this initial function by using a typeclass.<br /><br />I feel like this has not been addressed in your post. What are your thoughts on this matter?Qqwyhttps://www.blogger.com/profile/08742464027743784085noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-29919868512654467972017-05-27T11:46:45.142-07:002017-05-27T11:46:45.142-07:00The problem isn't the number of implementation...The problem isn't the number of implementations, but rather the lack of a specification. The reason laws matter is that they serve as a specification for a class.<br /><br />Without a specification a type class instance is "not even wrong". You can't discern whether or not the instance satisfies the intended purpose because you never precisely stated the intended purpose for the class in the form of laws.<br /><br />Yes, there are two `Monoid` instances for `Bool`, but that's fine because the specification says that any implementation is okay as long as `mempty` is empty with respect to `mappend`. However, there is no specification for the `Default` class and therefore no acceptance/rejection criteria for instances.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-43569174509609985952017-05-27T10:51:10.778-07:002017-05-27T10:51:10.778-07:00>>> " Without laws you can't jus...>>> " Without laws you can't justify one instance over another." <<<<br />---<br />Laws do not help me in this justification. A type has multiple values probably because all are needed and different values are right in different situations. A default is not right in some theoretical way, but rather just a value that is assumed most of the times [even just by convention].<br />A good example on the law-less side is (Foldable List). It is a problem-less instance, because probably everyone would implement it as it is in package "base".<br />A good examples on the law-ed side is (Monoid Bool). I not only can not justify one possible instance over the other but i can not even pick one for default.<br />So it is not the presence of laws that make a value good default of a type, or an instance implementation good choice for a (type-class, type) pair.libeakohttps://www.blogger.com/profile/01584915094701732892noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-64121960345385827512017-05-27T10:24:37.922-07:002017-05-27T10:24:37.922-07:00I made a mistake.
Instead of
"for the tuple...I made a mistake. <br />Instead of <br />"for the tuple type (T, dictionary_type_of C)"<br />i should have written <br />"of type (dictionary_type_of C T)"libeakohttps://www.blogger.com/profile/01584915094701732892noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-81636446844494322362017-05-27T09:45:05.853-07:002017-05-27T09:45:05.853-07:00I'm not saying that all type classes should be...I'm not saying that all type classes should behave like `Monoid`, but rather just the `Default` class<br /><br />However, even if you broaden the scope of the discussion to classes other than `Monoid` I still disagree. Without laws you can't justify one instance over another. For example, I could define the following alternative `Foldable` instance for lists:<br /><br />....instance Foldable [] where<br />........foldr cons nil [] = nil<br />........foldr cons nil (x:_) = cons x nil<br /><br />... and without any laws how could I argue for one instance over another?Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-16015939279441403702017-05-27T09:32:11.394-07:002017-05-27T09:32:11.394-07:00I sympathize with the main teaching of this post. ...I sympathize with the main teaching of this post. But i consider it not totally true. The mistake is the assumption that the default value should be empty somehow. That is false sometimes. An example is type-classes. Defining an instance of a class C for type T is mathematically equivalent to defining a default value for the tuple type (T, dictionary_type_of C). For example : defining a Foldable instance is equivalent to specifying default value of ((a -> b -> b) -> b -> t a -> b) [a 'foldr' function]. I can not think about foldr for List as empty somehow.libeakohttps://www.blogger.com/profile/01584915094701732892noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-40440168733440093442017-04-04T13:43:37.808-07:002017-04-04T13:43:37.808-07:00One of the reason that the `Default` instances ten...One of the reason that the `Default` instances tend to provide empty values anyway, even though they are not required to, is because they have to pick something that is universally useful since the type class instance has to be canonical for that type. If you have to pick only one value then the most obvious choice is the a value which is more distinguished than the rest, which is the "empty" value.<br /><br />I think "empty" would be a fine name for the empty value (if it weren't already taken by the Alternative class)Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-20529682564678492812017-04-02T10:47:46.318-07:002017-04-02T10:47:46.318-07:00That last "mappend" should have been &qu...That last "mappend" should have been "mempty".Nedhttps://www.blogger.com/profile/14481325116129501151noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-36933188540518412902017-04-02T10:42:59.468-07:002017-04-02T10:42:59.468-07:00The mention of "business logic" at the b...The mention of "business logic" at the beginning of this blog entry led me to believe it would address the sort of "default" one sees in typical "business logic", e.g. a default preference such as a blank screen saver. But the clear context (in the post, once I actually read it, as well as in Monoid itself), is of a value that causes a binary operation to simply yield its other argument, a "no effect" element, which of course describes "mempty". <br /><br />The Default typeclass itself requires no such context of a binary operator, yet all the -- ahem -- default instances provided dutifully supply either numeric zero or mempty, appearing to demonstrate that really, we're again intending the "noEffect" mathematical kind of default, not default screen savers. (And why would you specify a default screen saver using a typeclass instance anyhow, LOL?) Seems to me a strong case for using Monoid instead of Default (which as I understand it, is Gabriel's point).<br /><br />Maybe a nicer name for Monoid's identity element would have been "noEffect". Of course, when we get to Group, it takes on a somewhat expanded role; it's now also the result of combining an element with its inverse. What's the best name for that role -- "ash", "detritus"...? What one name covers both roles? Maybe "nothing"? Oops, taken. <i>Maybe</i> not. How about just "mappend"? Sigh.Nedhttps://www.blogger.com/profile/14481325116129501151noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-39827998388298795762013-04-10T11:35:34.480-07:002013-04-10T11:35:34.480-07:00FYI readers: there's actually a Default type c...FYI readers: there's actually a Default type class [1] which uses mempty for most of the stuff.<br /><br />[1] http://hackage.haskell.org/packages/archive/data-default/0.5.3/doc/html/Data-Default.htmlLuca Brunohttps://www.blogger.com/profile/06329046616630750783noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-27299386483618059022013-04-10T08:55:02.024-07:002013-04-10T08:55:02.024-07:00Yeah. :)
Surprisingly useful for such a simple co...Yeah. :)<br /><br />Surprisingly useful for such a simple concept, especially once you start generalizing it to Alternatives and Categories.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-14154427398233910982013-04-10T08:53:53.723-07:002013-04-10T08:53:53.723-07:00Monoids everywhere :)Monoids everywhere :)Sawadyhttps://www.blogger.com/profile/15647975101406450223noreply@blogger.com