tag:blogger.com,1999:blog-1777990983847811806.post6068538893084478665..comments2024-03-16T16:29:29.582-07:00Comments on Haskell for all: Scrap your type classesGabriella Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comBlogger60125tag:blogger.com,1999:blog-1777990983847811806.post-75887461621238920242021-04-22T15:37:29.808-07:002021-04-22T15:37:29.808-07:00Tried it in Elm already. That's how I know it ...Tried it in Elm already. That's how I know it doesn't work. The reason is the lack of a forall mechanism (i.e. support for rank 2 types).Dhttps://www.blogger.com/profile/12899102576877916413noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-36430698109914975672021-03-03T20:24:50.649-08:002021-03-03T20:24:50.649-08:00Made version compiling in GHC 8.8.3 and few style ...Made version compiling in GHC 8.8.3 and few style changes. https://gist.github.com/pedrofurla/c71af71680f9c224c3f469f86bef3c88, you look at the history for the exact changes.Pedro Furlanettohttps://www.blogger.com/profile/14664215916961577508noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-23659962797974360482020-05-11T15:20:53.517-07:002020-05-11T15:20:53.517-07:00He's not asking if Elm will implement it. He&#...He's not asking if Elm will implement it. He's asking if end-developers can implement the type class pattern without Elm actually having type classes.<br /><br />The answer is no. The language requires rank 2 types which Elm does not (yet) support.<br /><br />That being said, type classes (and rank 2 types by inclusion) have been requested and are being considered: https://github.com/elm/compiler/issues/238.Dhttps://www.blogger.com/profile/12899102576877916413noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-3437963220129238362019-10-19T17:46:05.375-07:002019-10-19T17:46:05.375-07:00Why wouldn't it? Try the examples in Elm and s...Why wouldn't it? Try the examples in Elm and see what happens.Michael Rogerhttps://www.blogger.com/profile/08729150476888743293noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-28006254403826750632019-04-27T11:18:36.571-07:002019-04-27T11:18:36.571-07:00Dear Anthony. Elm is quite popular for not impleme...Dear Anthony. Elm is quite popular for not implementing it on purpose. And this will likely never change. Anonymoushttps://www.blogger.com/profile/07503638614261007167noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-81201179400280910892019-03-23T03:59:20.131-07:002019-03-23T03:59:20.131-07:00Is it possible to implement this pattern in Elm? Is it possible to implement this pattern in Elm? Anthony Raimondohttps://www.blogger.com/profile/11471022230100674126noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-61699838288591960732017-09-02T18:21:19.934-07:002017-09-02T18:21:19.934-07:00I think type classes might be more optimized than ...I think type classes might be more optimized than explicit dictionary passing but I'm not sureGabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-54633905296559245672017-09-01T18:56:33.901-07:002017-09-01T18:56:33.901-07:00Hm you're right, I had the intuition that it c...Hm you're right, I had the intuition that it could be true but I wasn't sure.<br />Regarding perf, is there a risk of losing some of it (in the current haskell which isn't expecting the use of manual classes so to speak)? I just ask randomly, i don't really know much about performance and haskell's class system (or about performance in haskell in general).<br /><br />Off-topic, i couldn't reply directly to your answer, the javascript "reply" links don't seem to work for me...Anonymoushttps://www.blogger.com/profile/05521482717502138557noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-86204453492394060592017-09-01T18:37:14.694-07:002017-09-01T18:37:14.694-07:00I think the functional dependency mainly affects h...I think the functional dependency mainly affects how to resolve which instance to select, so if the user is already manually resolving the instances in the dictionary-based encoding then the presence or absence functional dependencies wouldn't matterGabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-87595537399682656632017-09-01T08:25:03.241-07:002017-09-01T08:25:03.241-07:00Hello! Very interesting article. I like the idea, ...Hello! Very interesting article. I like the idea, but i admit i'd never bear to use haskell with so much boilerplate and constant local binding of monomorphic functions... we'd need some serious sugar to handle all this.<br />It's still a fascinating approach, which can at the very least be right now a viable alternative to classes, esp those not meant to be used across packages/programs, esp when the class system is pushed to its limit.<br /><br />At any rate, i'm wondering what you do of the functional dependency of say (MonadState s m | m -> s). Is the information encoded in some way in the record type?Anonymoushttps://www.blogger.com/profile/05521482717502138557noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-59161044525426500542016-11-12T18:40:14.519-08:002016-11-12T18:40:14.519-08:00I'm going to assume that by "generic prog...I'm going to assume that by "generic programming" you mean the same thing as Java-style generics and what Haskell programmers call parametric polymorphism. If not, just let me know<br /><br />So this post is about what Haskell programmers call ad-hoc polymorphism, but ad-hoc polymorphism is just a special case of parametric polymorphism (and this blog post is really just a long-winded explanation of that statement)<br /><br />For example, the following type uses parametric polymorphism (i.e. the type "a" has no constraints at all):<br /><br /> example :: a -> a -> a<br /><br />... and the equivalent ad-hoc polymorphism would be:<br /><br /> class Example a where<br /> foo :: a<br /> bar :: a<br /><br /> example2 :: Example a => aGabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-25739395118622918122016-11-10T12:05:17.564-08:002016-11-10T12:05:17.564-08:00Can this technique be adapted for C++ generic prog...Can this technique be adapted for C++ generic programming?Dennishttps://www.blogger.com/profile/03601234553344631838noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-60773771986307973962016-06-07T18:12:46.932-07:002016-06-07T18:12:46.932-07:00This post makes me suspect that issues with typecl...This post makes me suspect that issues with typeclasses and issues with records are very similar, and that there might be a common solution.a a a aa ahttps://www.blogger.com/profile/16831384421325030686noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-54367893878485436452015-11-08T11:26:53.886-08:002015-11-08T11:26:53.886-08:00Yeah, that talk made me appreciate the benefits of...Yeah, that talk made me appreciate the benefits of type classes much more. That and other reasons are why I've mellowed my opinion to "don't abuse type classes".Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-68839998831295532722015-11-06T03:55:48.062-08:002015-11-06T03:55:48.062-08:00By the way, I'm surprised you didn't used ...By the way, I'm surprised you didn't used the title "Type classes considered harmful". ;) But I guess this reference fits as well.Hjullehttps://www.blogger.com/profile/02446691479719432130noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-53142142934668394692015-11-06T03:53:42.186-08:002015-11-06T03:53:42.186-08:00This seems to be slightly relevant: http://www.you...This seems to be slightly relevant: http://www.youtube.com/watch?v=hIZxTQP1ifo Edward Kmett talks about how Haskell type classes are different and (in his opinion) more powerful then the similar constructs in other languages.<br />Specifically, the property that all diagrams commute (https://youtu.be/hIZxTQP1ifo?t=3947) doesn't seem to hold for this solution. <br /> That said, I agree that your approach is powerful and that type classes are often used unnecessarily, as you said, lens is a perfect example.<br /><br />Here is another discussion on the subject: https://www.reddit.com/r/haskell/comments/1j0awq/definitive_guide_on_when_to_use_typeclasses/.Hjullehttps://www.blogger.com/profile/02446691479719432130noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-66715374063541591532014-09-02T18:33:50.011-07:002014-09-02T18:33:50.011-07:00So my current stance is that "type classes wi...So my current stance is that "type classes with mathematical laws are okay". My reasoning is that laws let you reason abstractly about what the type class does without consulting the source code. So, for example, I'm okay with type classes like `Monad`, `Functor`, and `Monoid`, but not with type classes like `IsWritable` or `HasFoo`.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-52436778272765125722014-08-21T12:20:36.154-07:002014-08-21T12:20:36.154-07:00In your edit, you say your opinion on this has mel...In your edit, you say your opinion on this has mellowed since time of writing. Have you discovered an alternative solution that solves most of the issues you wrote about?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-70666588890723571552013-08-08T11:21:21.459-07:002013-08-08T11:21:21.459-07:00Oh yeah, that's right! `GADT`s are one way to...Oh yeah, that's right! `GADT`s are one way to package up type class instances into dictionaries that act like witnesses to that instance. If you're really interested in this line of inquiry I've heard that you can do even more powerful things along these lines using the `ConstraintKinds` extension, although I don't know the specific details.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-90909550219999848762013-08-08T09:25:00.226-07:002013-08-08T09:25:00.226-07:00Maybe, I only have a tenuous grasp of what you are...Maybe, I only have a tenuous grasp of what you are explaining--and in the field in general. The nuances are so important here so I may be off base, but here's what I'm thinking. I came to your page through a google search when I was trying to understand that manual section the passage:<br /><br />"For example, one possible application is to reify dictionaries: <br />data NumInst a where<br /> MkNumInst :: Num a => NumInst a<br /><br /> intInst :: NumInst Int<br /> intInst = MkNumInst<br /><br /> plus :: NumInst a -> a -> a -> a<br /> plus MkNumInst p q = p + q<br />"<br />The plus application here is similar to your sequence' example, except that the pattern match on MkNumInst implies Num a, (makes that dictionary available(?)). IOW, GADT's allow for this pattern match to make available (+) automatically based on the class constraint included in the MkNumInst definition. So its not a scrap of the type class system but instead somewhat of a fusion the system and the methodology you are writing about. T. Cookhttps://www.blogger.com/profile/18062068766512116726noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-10195578624159787072013-08-08T08:45:20.776-07:002013-08-08T08:45:20.776-07:00Can you explain more?Can you explain more?Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-37465967091441757332013-08-08T08:05:28.077-07:002013-08-08T08:05:28.077-07:00Nice. What you are discussing seems to be embraced...Nice. What you are discussing seems to be embraced by GADT's. See the <a href="http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/data-type-extensions.html#gadt-style" rel="nofollow">GHC manual 7.4.6</a>T. Cookhttps://www.blogger.com/profile/18062068766512116726noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-54773996606131441062013-07-28T08:52:22.398-07:002013-07-28T08:52:22.398-07:00Neat! I never knew that. That's an interesti...Neat! I never knew that. That's an interesting approach to use an object as a dictionary. It's certainly less clumsy than the Haskell equivalent unless you use Haskell's `RecordWildCard` extension to unpack all the methods.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-14846900150385114412013-07-28T02:22:29.141-07:002013-07-28T02:22:29.141-07:00> ... or you pass the MonadI instance as a para...> ... or you pass the MonadI instance as a parameter to the do block.<br /><br />This is pretty similar to how F# does it. A computation expression, which is the ~equivalent of a do-block, is started with an object that has a Bind and a Return method, plus a bunch of other optional ones that mostly only make sense because F# isn't pure. http://msdn.microsoft.com/en-us/library/dd233182.aspxTarmilhttps://www.blogger.com/profile/02652099798546294621noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-59129426049924251472013-06-14T05:05:40.047-07:002013-06-14T05:05:40.047-07:00The logic aspect is also interesting for me. I wil...The logic aspect is also interesting for me. I will read the tutorial paper on Agda.Anonymousnoreply@blogger.com