5 ms·
> there is one overall Haskell language and the absence of a particular language extension disables a particular feature. The language is, by and large, more co
by rattray 6y ago
> there is one overall Haskell language and the absence of a particular language extension disables a particular feature. The language is, by and large, more coherent with language extensions turned on
Right, that's exactly it! Almost nobody uses Haskell without un-disabling many features; in doing so, they discover "Real Haskell" and leave behind the less-coherent "Plain Haskell".
However, there is no central understanding (that I've ever seen) of what "Real Haskell" is. Everyone defines their own.
Beauty being in the eye of the beholder, it's thus no wonder that wizened Haskellers come back from the wilderness speaking of a thing of magnificence – for the Haskell they have seen is a Haskell they wrought. They found the extensions that suited them, and unlocked the "Real Haskell" of their dreams.
But for a new adventurer setting out, there is no one charted path to Nirvana; only swirling rumors, each as different as the next. Perhaps all travelers agree that a good bit of String is necessary to carry along, but it ends there.
This isn't to say that Haskell fails – there are many who love it, and its curiosities inspire much exploration in plainer realms – but.... well, you can see that it wouldn't be appealing to someone who wants to understand a system instead of playing a choose-your-own-adventure mystery game ;)
- tome 6y agoThis is a tale that people like to weave. I can only imagine that they haven't used Haskell much, or at least my experience is completely different. Sometimes I try to do something that seems sensible. The compiler says "you can't do this, you need to turn on -XExtension". I do so. The end. It's really not terribly mysterious or complicated.
- rattray 6y agoHmm, ok. Yeah that really doesn't sound so bad.
- dllthomas 6y ago> I do so. The end. Ehh... except the times it thinks I could do something with an extension, but it's not actually something I want to do. Still, it's very nice to have the starting point, and I agree it's not a bad experience overall. Edited to add an example: Prelude> 1 2 <interactive>:1:1: error: • Non type-variable argument in the constraint: Num (t1 -> t2) (Use FlexibleContexts to permit this) • When checking the inferred type it :: forall t1 t2. (Num t1, Num (t1 -> t2)) => t2 Prelude> :set -XFlexibleContexts Prelude> 1 2 <interactive>:3:1: error: • Could not deduce (Num t0) from the context: (Num t, Num (t -> t1)) bound by the inferred type for ‘it’: forall t t1. (Num t, Num (t -> t1)) => t1 at <interactive>:3:1-3 The type variable ‘t0’ is ambiguous • In the ambiguity check for the inferred type for ‘it’ To defer the ambiguity check to use sites, enable AllowAmbiguousTypes When checking the inferred type it :: forall t1 t2. (Num t1, Num (t1 -> t2)) => t2 Prelude> :set -XAllowAmbiguousTypes Prelude> 1 2 <interactive>:5:1: error: • No instance for (Num (Integer -> ())) arising from a use of ‘it’ (maybe you haven't applied a function to enough arguments?) • In the first argument of ‘print’, namely ‘it’ In a stmt of an interactive GHCi command: print it There's nothing wrong with enabling FlexibleContexts, but it's not going to solve your problem. You likely don't want AllowAmbiguousTypes on globally (though it's not as dangerous as it might sound). The final error message you get is the most useful, so going on this little journey isn't terrible, but it could have been short circuited if you took a beat to understand the extension it was asking for, and why it's being asked for in this context. Edited to add: The problem with the above code, of course, is that I'm trying to apply the function 1 to the value 2, but 1 doesn't represent a function. But it could! Because the way number literals in Haskell are handled is much the same way as OverloadedStrings works - 5 is treated as (fromInteger 5) - and they have type (Num a => a), so that the context gets to pick which numeric type they're interpreted as. As far as the language is concerned, I could make integer literals represent functions that (say) add that number to an input: instance Num (Integer -> Integer) where fromInteger n = (+ n) ... ... but that's not actually what I wanted. Almost certainly, it was a typo.
- tome 6y agoSure, you are an experienced Haskeller so you have seen the sharp end of this. If this were a Haskell forum I might be proclaiming we have too many language extensions and the error messages are terrible! As were are on a forum for generalists I think the fairest thing to do is to point out as strongly as possible that, no, extensions don't mean that Haskellers have to choose to learn one of several incompatible languages, they don't mean you have to learn anything more than just another language feature, they're really not an impediment to being successful with Haskell in any way, and the fact that they are extensions at all is a quirk of having a language defined by a standard.