-
Notifications
You must be signed in to change notification settings - Fork 145
GHC Language Options vs. Frege
This document discusses GHC language options that correspond to Frege features.
Frege has features that correspond more or less roughly to the following GHC language options:
-XUnicodeSyntax
-XRebindableSyntax
-XPostfixOperators
-XNamedFieldPuns
-XLiberalTypeSynonyms
(restricted) -XStandaloneDeriving
(different keyword)
-XTypeSynonymInstances
-XFlexibleInstances
(restricted) -XInstanceSigs
-XRankNTypes
-XNoMonomorphismRestriction
-XRelaxedPolyRec
-XMonoLocalBindings
-XBangPatterns
Read on to learn more details.
The following unicode symbols are recognized and interpreted:
- ← U+2190 LEFTWARDS ARROW is interpreted as
<-
- → U+2192 RIGHTWARDS ARROW is interpreted as
->
- ⇒ U+21D2 RIGHTWARDS DOUBLE ARROW is interpreted as
=>
- ∀ U+2200 FOR ALL is interpreted as keyword
forall
- ∷ U+2237 PROPORTION is interpreted as
::
- … U+2026 HORIZONTAL ELLIPSIS is interpreted as
..
The interpretation takes place only if the symbol stands alone and is not part of some operator, i.e.
a ←| b
is not the same as
a <-| b
Frege module names map to class names of the underlying platform (i.e. JVM). Thus, they are hierarchical by nature.
Because classes with simple names cannot get imported from classes with qualified names due to restrictions of the JVM, the prelude module is named frege.Prelude
.
Pattern guards are part of Haskell 2010 and as such are no GHC extension anymore, though they are still listed on the linked page. They're fully supported in Frege.
Negation, e.g. -(f x)
, means negate (f x)
and whatever negate
is in scope will be used.
do notation is translated using whatever functions (>>=)
, (>>)
and fail
are in scope.
Right operator sections, e.g. (
`op
` v)
are translated to flip (op) (v)
using whatever flip
function is in scope.
Left operator sections, e.g. (v
`op
`)
are translated to (op) (v)
. Unlike with GHC, this is also allowed on the left hand side of function definitions:
infix 1 `³` -- make ³ an operator (associativity and precedence immaterial)
(x³) = x^3 -- legal
Remember that applications of such a postfix operator must always occur in the form of a section or in prefix form, as the operator is syntactically still treated as a binary one.
Record puns are supported in patterns, record constructor applications and record update expressions.
The right hand side of a type definition can be a forall
type:
type Discard a = forall b. Show b => a -> b -> (a, String)
Currently, a type synonym may not be applied to a forall
type.
A type synonym must not occur partially applied.
This is actually the only way to derive an instance in Frege. The keyword is derive
.
Instance heads may use type synonyms. So the following is legal.
type Point a = (a,a)
instance C (Point a) where ...
In addition, concrete types may be given instead of type variables. For example:
instance C (Maybe Int) where ...
However, for every class C
and type constructor T
there must be still at most one C
instance for applications of T
. For example, we may not subsequently define
instance C (Maybe Double) where ... -- wrong because of C (Maybe Int)
This is allowed in Frege, and the supplied signatures get checked for correctness.
Explicit forall
types can occur on the right hand side of a type definition, in type signatures (that is, following a ::
) or as arguments of constructor definitions. For example:
data T = T (forall x.x->x)
which is equivalent to the record notation:
data F = F {fun :: forall x.x->x}
as well as
type I = forall x. x->x
data T = T I
In Frege, we don't have the monomorphism restriction.
For top level bindings, this seems to work exactly like described in the GHC manual. For let bindings, see below.
The Frege compiler does not generalise let bound bindings at all. (This is a bit more radical and also simpler than what Haskell does).
The let bound bindings either do have a type signature, in which case they're left alone, or they don't, and the types of those latter ones are not generalised, but remain monomorphic.
In addition, bindings that have a signature and don't reference other local items are moved to the top level. Bindings that are used just once are inlined, unless they're recursive.
Unlike in GHC, a pattern with a bang at the outermost level is allowed at the top level of a module. At runtime, this has the effect that the value is computed (to WHNF) as soon as the class that results from compilation of the module is initialized. The rationale is that especially for numeric constants, one does not want to have an indirection introduced through a thunk.
Home
News
Community
- Online Communities
- Frege Ecosystem
- Frege Day 2015
- Protocol
- Simon Peyton-Jones Transcript
- Talks
- Articles
- Books
- Courses
Documentation
- Getting Started
- Online REPL
- FAQ
- Language and API Reference
- Libraries
- Language Interoperability
- Calling Frege From Java (old)
- Calling Java From Frege
- Calling Frege From Java (new)
- Compiler Manpage
- Source Code Doc
- Contributing
- System Properties
- License
- IDE Support
- Eclipse
- Intellij
- VS Code and Language Server
- Haskell
- Differences
- GHC Options vs Frege
- Learn You A Haskell Adaptations
- Official Doc
Downloads