| Start | |||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RankNTypes Imagine the following situation: Here, we want to pass in a function that converts a value into a String, apply that function to both a string parameter and and int parameter and print them both. In my mind, there is no reason this should fail! We have a function that works on both types of the parameters we're passing in. Unfortunately, this won't type check! GHC infers the GHC will infer that
This is rank 2 polymorphism: We are asserting that the The |
|||||||||||||||||||||||||||||||||
| OverloadedStrings Normally, string literals in Haskell have a type of
Allowing them to be directly passed to functions expecting such a type. Many libraries implement this interface for their string-like types including Data.Text (opens new window) and Data.ByteString (opens new window) which both provide certain time and space advantages over There are also some unique uses of To create a instance of the † This example courtesy of Lyndon Maydwell ( |
|||||||||||||||||||||||||||||||||
| BinaryLiterals Standard Haskell allows you to write integer literals in decimal (without any prefix), hexadecimal (preceded by |
|||||||||||||||||||||||||||||||||
| ExistentialQuantification This is a type system extension that allows types that are existentially quantified, or, in other words, have type variables that only get instantiated at runtime†. A value of existential type is similar to an abstract-base-class reference in OO languages: you don't know the exact type in contains, but you can constrain the class of types. or equivalently, with GADT syntax: Existential types open the door to things like almost-heterogenous containers: as said above, there can actually be various types in an Now we can create a collection of such objects: Which also allows us to use the polymorphic behaviour: Existentials can be very powerful, but note that they are actually not necessary very often in Haskell. In the example above, all you can actually do with the On the other hand, existentials cause some unique problems. For instance, the way the type information is “hidden” in an existential. If you pattern-match on an †Contrast this with ordinary parametric polymorphism, which is generally resolved at compile time (allowing full type erasure). Existential types are different from Rank-N types – these extensions are, roughly speaking, dual to each other: to actually use values of an existential type, you need a (possibly constrained-) polymorphic function, like |
|||||||||||||||||||||||||||||||||
| LambdaCase A syntactic extension that lets you write Consider the following function definition: If you want to avoid repeating the function name, you might write something like: Using the LambdaCase extension, you can write that as a function expression, without having to name the argument: |
|||||||||||||||||||||||||||||||||
| FunctionalDependencies If you have a multi-parameter type-class with arguments a, b, c, and x, this extension lets you express that the type x can be uniquely identified from a, b, and c: When declaring an instance of such class, it will be checked against all other instances to make sure that the functional dependency holds, that is, no other instance with same You can specify multiple dependencies in a comma-separated list: For example in MTL we can see: Now, if you have a value of type The |
|||||||||||||||||||||||||||||||||
| FlexibleInstances Regular instances require: That means that, for example, while you can create an instance for |
|||||||||||||||||||||||||||||||||
| GADTs Conventional algebraic datatypes are parametric in their type variables. For example, if we define an ADT like with the hope that this will statically rule out non-well-typed conditionals, this will not behave as expected since the type of Generalised Algebraic Data Types allows us to control the resulting type of a data constructor so that they are not merely parametric. We can rewrite our Here, the type of the constructor Pattern matching on a GADT value causes refinement of the type of the term returned. For example, it is possible to write an evaluator for Note that we are able to use |
|||||||||||||||||||||||||||||||||
| TupleSections A syntactic extension that allows applying the tuple constructor (which is an operator) in a section way: N-tuplesIt also works for tuples with arity greater than two MappingThis can be useful in other places where sections are used: The above example without this extension would look like this: |
|||||||||||||||||||||||||||||||||
| OverloadedLists added in GHC 7.8. OverloadedLists, similar to OverloadedStrings (opens new window), allows list literals to be desugared as follows: This comes handy when dealing with types such as
Examples taken from OverloadedLists – GHC (opens new window). |
|||||||||||||||||||||||||||||||||
| MultiParamTypeClasses It's a very common extension that allows type classes with multiple type parameters. You can think of MPTC as a relation between types. The order of parameters matters. MPTCs can sometimes be replaced with type families. |
|||||||||||||||||||||||||||||||||
| UnicodeSyntax An extension that allows you to use Unicode characters in lieu of certain built-in operators and names.
For example: would become Note that the |
|||||||||||||||||||||||||||||||||
| PatternSynonyms Pattern synonyms (opens new window) are abstractions of patterns similar to how functions are abstractions of expressions. For this example, let's look at the interface But this representation is unwieldy and some of its invariants cannot be expressed in Haskell's type system. Because of this, the But using this interface can be a bit cumbersome: We can use view patterns (opens new window) to clean it up somewhat: Using the This allows us to write |
|||||||||||||||||||||||||||||||||
| ScopedTypeVariables
The important thing is that we can use |
|||||||||||||||||||||||||||||||||
| RecordWildCards See RecordWildCards (opens new window) RemarksThese language extensions are typically available when using the Glasgow Haskell Compiler (GHC) as they are not part of the approved Haskell 2010 language Report (opens new window). To use these extensions, one must either inform the compiler using a flag (opens new window) or place a The format of the |
Read Article
https://develop.horje.com/learn/1434/reference