Coder Social home page Coder Social logo

haskell-src-exts's Introduction

Haskell Source Extensions

haskell-src-exts is a package for handling and manipulating Haskell source code. It is a descendant of the haskell-src package that is part of the standard libraries, but extends this to support a number of syntactic extensions, e.g. MPTCs, fundeps, GADTs, TH etc. The aim is to support all extensions recognized by the community, as determined by what is implemented in compilers and tools.

Apart from the more standard extensions supported by e.g. GHC, haskell-src-exts provides support for HaRP (Haskell Regular Patterns) and HSX (Haskell Source with XML) syntax.

Package structure

The modules that comprise haskell-src-exts all reside in the hierarchic namespace Language.Haskell.Exts. Notable exposed modules include:

  • Language.Haskell.Exts - Imports and re-exports all the below, and also defines some functions that combine functionality from several modules.
  • Language.Haskell.Exts.Syntax - The abstract syntax tree that the other modules work on.
  • Language.Haskell.Exts.Build - Combinators for building abstract syntax.
  • Language.Haskell.Exts.Parser - Functions for parsing Haskell source code into an abstract syntax representation.

License

The haskell-src-exts Package is distributed under a derived BSD-style license. It derives from several sources, all of which are distributable under BSD-style or compatible licenses. See the file LICENSE for the complete license text.

Maintenance

Dan Burton is currently keeping haskell-src-exts on life support. If you are interested in more actively making improvements to this package, please make your interests known.

You might want to try ghc-lib-parser instead.

haskell-src-exts's People

Contributors

aavogt avatar alanz avatar ashleyyakeley avatar asr avatar bgamari avatar cocreature avatar danburton avatar dzhus avatar erikd avatar greenrd avatar hesselink avatar jpmoresmau avatar lexi-lambda avatar meiersi avatar mgsloan avatar mpickering avatar ndmitchell avatar nh2 avatar niklasbroberg avatar pepeiborra avatar phadej avatar phischu avatar pjonsson avatar ptrhlm avatar ryanglscott avatar skogsbaer avatar sopvop avatar stiiin avatar tolysz avatar unkindpartition avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

haskell-src-exts's Issues

Arrow control operators (form, banana brackets) are not supported

Currently, all Arrow notation can be parsed, except the banana brackets (which corresponds to the form keyword in Ross Paterson's paper), thereby making support for Arrows incomplete.

Minimal example, which parses and type-checks in GHC, and fails to parse in HSE and HSEA:

{-# LANGUAGE Arrows #-}
f :: a -> a
f = proc x -> (| undefined |)

This is also blocking me from conveniently desugaring recrusive arrow notation, which involves translation into an expression that contains form.

The `knownExtensions` function is ill-defined!

In haddock, knownExtensions is described as "List of all known extensions, all enabled.", that is the same as previous versions.

But its definition seems wrong:

knownExtensions :: [Extension]
knownExtensions =
  concat [ [EnableExtension x, DisableExtension x] | x <- [minBound..maxBound] ]

This code enables all extensions at first then disables them! This is not match its description.
This change causes unexpected behaviours. For example, haskell-src-exts-qq, compiled with haskell-src-exts-1.14.0, cannot treat splices correctly, for the TemplateHaskell extension disabled right after it's enabled!

Support type splices

According to the GHC docs types should support splices. Could this be added to haskell-src-exts so the following module could be parsed?

{-# LANGUAGE TemplateHaskell #-} 
module Main (main) where 

main = print t1 

t1 :: $( [t|Int| ]) 
t1 = 1

Illegal class assertion with parenthesized type equality constraint

By @byorgey:

This sample code is accepted by GHC but not by HSE:

{-# LANGUAGE TypeFamilies #-}                  
f :: ( Eq a, (a ~ Int) ) => a -> Int
f _ = 3

HSE fails with a parse error "Illegal class assertion". Removing the
parentheses around (a ~ Int) causes it to be accepted.

Note that the following example is accepted by both HSE and GHC:

f :: ( Eq a, (Ord a) ) => a -> Int
f _ = 3

Even though, by my reading, parentheses around individual class
constraints are not technically allowed by the Report.

Record wildcard syntax is more lenient than in GHC

It seems that GHC only permits record wildcard .. as the last item inside braces. E.g.

> let f A { .., b = v } = v

<interactive>:15:13: parse error on input `,'

HSE, on the other hand, permits wildcards in any position, and even permits multiple occurrences:

> void $ parseModuleWithMode defaultParseMode {extensions = [EnableExtension  RecordWildCards]} "f A { .., b = v, .. } = v"
ParseOk ()

I think GHC's behaviour makes more sense here. Also, that would allow tor restructure the AST in a more convenient way — e.g. make this a boolean flag indicating whether the given pattern or update has a wildcard.

This is also worth discussing with the Haskell2014 committee, see http://ghc.haskell.org/trac/haskell-prime/ticket/137

Discrepancy between instance declarations: type families vs. type classes

There is a discrepancy between the way instances of type families and type classes are represented in HSE.

data Decl l
    ...

So far so good.

    ...
    | TypeInsDecl  l     (Type l) ...
    | DataInsDecl  l ... (Type l) ...
    | GDataInsDecl l ... (Type l) ...
    ...

This is a very broad type, which is not too type-safe, but it might be handy for some applications to have an instance head to be presented like this.

    ...
    | InstDecl     l (Maybe (Context l)) (InstHead l) ...
    | DerivDecl    l (Maybe (Context l)) (InstHead l)
    ...

This is a much narrower type, but at least we can be sure that the type will be like C t1 .. tn, which is helpful in certain situations. However, it's currently too narrow and it causes problems (see #9), so it should perhaps include (Maybe [TyVarBind l]). It might even be useful to absorb these two fields into the InstHead data type.

For Language.Haskell.Exts.Syntax it's worse.

data Decl
    ...
    | TypeInsDecl  SrcLoc     Type ...
    | DataInsDecl  SrcLoc ... Type ...
    | GDataInsDecl SrcLoc ... Type ...
    ...

For type families, nothing really changes.

    ...
    | InstDecl     SrcLoc Context QName [Type] ...
    | DerivDecl    SrcLoc Context QName [Type]
    ...

For type classes, there isn't even an InstHead data type.

I suggest that all these cases should be turned into one encoding, be it Types or InstHeads. In my opinion, InstHead is the most HSE-ish approach here.

Fixity resolution incorrectly handles shadowed operators

By @BenMachine:

When an operator name is shadowed, haskell-src-exts continues to use the fixity from the outer scope. This is obviously wrong when the operator carries its own fixity declaration (I think this is merely a problem of adding the new fixities to the front of the list rather than the back) but in fact shadowing an operator without a fixity declaration should reset it to infixl 9 - so we have the somewhat trickier problem of detecting when any new operator names are introduced that might shadow an outer definition. In the extreme case with TH or a quasiquoter this is actually impossible, I think, but it would still be nice to respect the (admittedly quite rare) case of an operator name defined inline.

An example of where this would go wrong is the following definition that lambdabot gives for on:

(*) `on` f = \x y -> f x * f y

In the RHS here, HSE would give * fixity 7, when it should really have fixity 9. In this case it wouldn't make a difference, but it's not hard to construct cases where it would.

Parseable instances for other ast types

Currently, there are only parsers for Module Exp, Stmt, Pat, Decl, and Type. This causes people to resort to hacks like using parseModule variants to parse [Decl]. While this approach extends to all HSE types, it doesn't seem quite right, when most of these parsers exist, but aren't exposed.

Parsing of MultiParamTypeClasses constraints fails without the extension, GHC allows this

Test2.hs:

{-# LANGUAGE MultiParamTypeClasses #-}
module Test2 where

class A a where
class B b where

newtype N a = N a

class (A from,B to) => C from to where
  fromTo :: from -> N to

Test.hs:

module Test where

import Test2

f :: C from to => (from -> N to) -> ()
f _ = ()
$ ghc Test.hs -fno-code -Wall
[1 of 2] Compiling Test2            ( Test2.hs, nothing )
[2 of 2] Compiling Test             ( Test.hs, nothing )
λ> Language.Haskell.Exts.Annotated.parseFile "Test.hs"
ParseFailed (SrcLoc {srcFilename = "Test.hs", srcLine = 5, srcColumn = 19}) "MultiParamTypeClasses is not enabled"

Is GHC being too lenient or should this parse with haskell-src-exts?

qualified quasiquote fails to parse

Here is a reproduce case which exhibit issues when using qualified import quasiquoters:

import           Language.Haskell.Exts

main :: IO ()
main = print $ parseModuleWithMode parseMode string
  where
    parseMode = defaultParseMode
        { extensions = [EnableExtension FlexibleInstances, EnableExtension TemplateHaskell, EnableExtension QuasiQuotes]
        }

string :: String
string = unlines
    [ "{-# LANGUAGE FlexibleInstances #-}"
    , "{-# LANGUAGE TemplateHaskell #-}"
    , "{-# LANGUAGE QuasiQuotes #-}"
    , ""
    , "import qualified Language.Haskell.TH as T"
    , ""
    , "x :: DecsQ"
    , "x = [T.d|id|]"
    ]

which fails with this message:

ParseFailed (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 8, srcColumn = 12}) "Parse error: |]"

Parse error on bracketed instance head

By @ndmitchell:

module A where instance (Bounded a => Bounded [a]) where 

This parses in GHC, but not in HSE. Originally reported by Eric Kow against derive, but would also effect hlint etc. It's possible GHC is in error here (I don't know the report parsing rules well enough), so this might need raising against GHC.

Fails to parse qualified record punning

Originally reported against stylishHaskell: haskell/stylish-haskell#30

I'm getting

Language.Haskell.Stylish.Parse.parseModule: could not parse : ParseFailed (SrcLoc {srcFilename = ".hs", srcLine = 353, srcColumn = 35}) "Illegal qualified name"

for the following line of code:

cotile = tile {Kind.ospeedup}

which otherwise works perfectly in GHC.

Test case exists in Test/examples/RecordPuns.hs

Fixity resolution enhancement

Originally requested by @ndmitchell, two related improvements:

  1. If a parse results in a fixity error it should be reported through ParseError, not by raising error.
  2. The applyFixities function is very limited. A better signature would be:
applyFixities :: a -> ([FixityError],a) 

Now when there is a fixity error you get back a list of the errors, and a revised document with as many fixities resolved as possible. This would be particularly useful for HLint: http://code.google.com/p/ndmitchell/issues/detail?id=302

And more generally, it should suit any user of HSE. With a simple FixityError -> ParseError function the apply fixities could easily be reused for the main parsing.

Compilation error with ghc HEAD (7.7.20131106)

[19 of 22] Compiling Language.Haskell.Exts.InternalParser ( dist/build/Language/Haskell/Exts/InternalParser.hs, dist/build/Language/Haskell/Exts/InternalParser.o )
templates/GenericTemplate.hs:104:22:
    Couldn't match expected type ‛Bool’
                with actual type ‛Happy_GHC_Exts.Int#’
    In the expression:
      (n Happy_GHC_Exts.<# (0# :: Happy_GHC_Exts.Int#))
    In a stmt of a pattern guard for
                   a case alternative:
      (n Happy_GHC_Exts.<# (0# :: Happy_GHC_Exts.Int#))
    In a case alternative:
        n | (n Happy_GHC_Exts.<# (0# :: Happy_GHC_Exts.Int#))
          -> (happyReduceArr Happy_Data_Array.! rule) i tk st
          where
              rule
                = (Happy_GHC_Exts.I#
                     ((Happy_GHC_Exts.negateInt#
                         ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#))))))

templates/GenericTemplate.hs:115:23:
    Couldn't match expected type ‛Bool’
                with actual type ‛Happy_GHC_Exts.Int#’
    In the expression:
      (off_i Happy_GHC_Exts.>=# (0# :: Happy_GHC_Exts.Int#))
    In the expression:
      if (off_i Happy_GHC_Exts.>=# (0# :: Happy_GHC_Exts.Int#)) then
          (indexShortOffAddr happyCheck off_i Happy_GHC_Exts.==# i)
      else
          False
    In an equation for ‛check’:
        check
          = if (off_i Happy_GHC_Exts.>=# (0# :: Happy_GHC_Exts.Int#)) then
                (indexShortOffAddr happyCheck off_i Happy_GHC_Exts.==# i)
            else
                False

templates/GenericTemplate.hs:117:30:
    Couldn't match expected type ‛Happy_GHC_Exts.Int#’
                with actual type ‛Bool’
    In the expression: False
    In the expression:
      if (off_i Happy_GHC_Exts.>=# (0# :: Happy_GHC_Exts.Int#)) then
          (indexShortOffAddr happyCheck off_i Happy_GHC_Exts.==# i)
      else
          False

templates/GenericTemplate.hs:119:13:
    Couldn't match expected type ‛Bool’
                with actual type ‛Happy_GHC_Exts.Int#’
    In the expression: check
    In a stmt of a pattern guard for
                   a pattern binding:
      check

templates/GenericTemplate.hs:212:14:
    Pattern bindings containing unlifted types should use an outermost bang pattern:
      (sts1@((HappyCons (st1@(action)) (_))))
        = happyDrop k (HappyCons (st) (sts))
    In an equation for ‛happyMonadReduce’:
        happyMonadReduce k nt fn j tk st sts stk
          = happyThen1
              (fn stk tk)
              (\ r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))
          where
              (sts1@((HappyCons (st1@(action)) (_))))
                = happyDrop k (HappyCons (st) (sts))
              drop_stk = happyDropStk k stk

templates/GenericTemplate.hs:219:14:
    Pattern bindings containing unlifted types should use an outermost bang pattern:
      (sts1@((HappyCons (st1@(action)) (_))))
        = happyDrop k (HappyCons (st) (sts))
    In an equation for ‛happyMonad2Reduce’:
        happyMonad2Reduce k nt fn j tk st sts stk
          = happyThen1
              (fn stk tk)
              (\ r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))
          where
              (sts1@((HappyCons (st1@(action)) (_))))
                = happyDrop k (HappyCons (st) (sts))
              drop_stk = happyDropStk k stk
              (off) = indexShortOffAddr happyGotoOffsets st1
              (off_i) = (off Happy_GHC_Exts.+# nt)
              ....

Here's my ghc -v:

Glasgow Haskell Compiler, Version 7.7.20131106, stage 2 booted by GHC version 7.6.3
Using binary package database: /usr/local/lib/ghc-7.7.20131106/package.conf.d/package.cache
Using binary package database: /Users/schell/.ghc/x86_64-darwin-7.7.20131106/package.conf.d/package.cache
wired-in package ghc-prim mapped to ghc-prim-0.3.1.0-e46956cad40995d806d21a12caed6e94
wired-in package integer-gmp mapped to integer-gmp-0.5.1.0-2e41ffaefd9e5bad3171884486a8899b
wired-in package base mapped to base-4.7.0.0-b0a03fcafbec65366d8c02c935053de2
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.9.0.0-01c310fe1b1b623eb903ad4c41b60c15
wired-in package dph-seq not found.
wired-in package dph-par not found.

Incorrect formatting of WarningText declaration

This patch fixes the formatting of WARNING and DEPRECATED pragmas:

--- old-haskell-src-exts/src/Language/Haskell/Exts/Pretty.hs    2013-05-24 13:03:36.037896671 -0700
+++ new-haskell-src-exts/src/Language/Haskell/Exts/Pretty.hs    2013-05-24 13:03:36.097896668 -0700
@@ -284,8 +284,8 @@
         text "where"]

 ppWarnTxt :: WarningText -> Doc
-ppWarnTxt (DeprText s) = mySep [text "{-# DEPRECATED", text s, text "#-}"]
-ppWarnTxt (WarnText s) = mySep [text "{-# WARNING",    text s, text "#-}"]
+ppWarnTxt (DeprText s) = mySep [text "{-# DEPRECATED", text (show s), text "#-}"]
+ppWarnTxt (WarnText s) = mySep [text "{-# WARNING",    text (show s), text "#-}"]

 instance Pretty ModuleName where
         pretty (ModuleName modName) = text modName

retire Generic Haskell support

There are two good reasons to remove all support for Generic Haskell from haskell-src-exts:

  1. As far as I know, Generic Haskell is dead. The last version of the official compiler was released over five years ago (April 2008) and fails to build from source. The graduate course "Generic Programming" at Utrecht University (which hosts the GH compiler) only mentions Generic Haskell as a historical artifact.
  2. Generic Haskell support at type-level is completely broken. The only support seems to be of {| |} in patterns, but haskell-src-exts chokes on {[ ]} in type signatures.

Poor error message with RecordWildCards

Given the source:

foo Record{..} = xs

The error message is:
Sample.hs:2:14: Parse error, RecordWildCards is not enabled

However, the .. goes from column 12 to 14, so column 12 would be a much better position for the error message. This shows up more visibly if you have an editor which is parsing on the fly and drawing red underlines.

Unexpected source locations for implicit blocks

Given the module:

foo = x where x = 1



y = 2

The SrcInfo on the PatBind for foo extends to the very beginning of the y, so srcSpanEndLine = 5, rather than 1. Technically this is not incorrect, but the principle of least surprise dictates that it is probably undesired.

Monoid for SrcSpan and SrcSpanInfo?

There're a couple things in the way of having a proper Monoid for SrcSpan and SrcSpanInfo:

  • A good representation for empty. The existence of noLoc = SrcLoc "" (-1) (-1) sets a precedent for this representing an empty location / interval.
  • If mergeSrcSpan had a special case for empty, then it would be a proper definition for mappend. combSpanInfo / (<++>) throw away srcInfoPoints, which isn't so nice. You could still have a proper mappend, though, if they preserved srcInfoPoints when combined with mempty.

Maybe it would be better to have an explicit representation for empty SrcLoc and SrcSpan? Main issue is that it would be quite a breaking change.

parseStmt variants don't use fixities

For example, these ought to behave similarly:

> parseStmt "1 + 2 * 3"
ParseOk (Qualifier (InfixApp (InfixApp (Lit (Int 1)) (QVarOp (UnQual (Symbol "+"))) (Lit (Int 2))) (QVarOp (UnQual (Symbol "*"))) (Lit (Int 3))))
> parseExp "1 + 2 * 3"
ParseOk            (InfixApp (Lit (Int 1)) (QVarOp (UnQual (Symbol "+"))) (InfixApp (Lit (Int 2)) (QVarOp (UnQual (Symbol "*"))) (Lit (Int 3))))

PNeg should not exist

@BenMachine writes:

One of the constructors for the Pat type is PNeg Pat, for negated patterns. But not only is the Pat field here way too general (since -n or -(x:xs) are not valid patterns), the only circumstances in which it is actually valid seem to be negated literals, which are either quite capable of storing that information in their literal, or quite inappropriate to be negated (and so should be an error). Notice that -1## is a parse error in GHC since word literals must be non-negative integers.

So there's firstly an arguable bug in that parsePat "-'a'" succeeds, producing ParseOk (PNeg (PLit (Char 'a'))) which is nonsense, but there's also a wider question of whether we need PNeg at all, or whether we can drop it in favour of negation inside the literals. NegApp is clearly necessary on expressions, but there's no analogous negation of variables or compound constructions in patterns.

failure to parse trailing where

The following code fails to parse:

module Error where

fail = x
    where
    broken = 24
        where
    x = 413

The problem is the trailing 'where' after 'broken', and the dedented
'x = 413' underneath. I think this trailing where should be legal,
from the 2010 report, section 2.7 (layout): If the indentation of the
non-brace lexeme immediately following a where, let,do or of is less
than or equal to the current indentation level, then instead of
starting a layout, an empty list “{}” is inserted, and layout
processing occurs for the current level (i.e. insert a semicolon or
close brace).

So that where should get a {} after it, and parse successfully. Also,
haskell-src-exts is usually fine with a trailing where, but that
specific combination makes it unhappy. And GHC has no problem with
any of it.

Please merge 'alternatives'

I often end up duplicating a lot of code because of the overlaps between PatBind, Alt and Rhs. Apart from following the Haskell 2010 report grammar to the letter, I'd rather see that these redundancies were removed.

  1. In the Decl data type, please turn

    PatBind l (Pat l) (Maybe (Type l)) (Rhs l) (Maybe (Binds l))
    

    into

    PatBind l (Maybe (Type l)) (Alt l)
    
  2. In the Alt data type, please turn

    Alt l (Pat l) (GuardedAlts l) (Maybe (Binds l))
    

    into

    Alt l (Pat l) (Rhs l) (Maybe (Binds l))
    

    and remove the GuardedAlts and GuardedAlt types.

Curly Brackets around deriving clause of GADTs

The pretty printer with explicit layout adds curly brackets around the deriving clause of GADTs. Example:

data StorableVector1k a where
   StorableVector1k :: [a] -> StorableVector1k a
   deriving ( Show, Eq )

is printed as

data StorableVector1k a where
         { StorableVector1k :: [a] -> StorableVector1k a}
     { deriving (Show, Eq)};

GHC does not accept the brackets around the deriving clause.

No support for record fields in GADT-style declarations

@hsenag reports:

This code is supported by GHC 6.12 and up, but not by HSE:

{-# LANGUAGE GADTs #-}
data Foo where
  Foo :: { x :: Int } -> Foo

There's also an old-style syntax which would also be nice to have because darcs (which I'm currently trying to push through HSE) still supports GHC 6.10

{-# LANGUAGE GADTs #-}
data Foo where
  Foo { x :: Int } :: Foo

Incoherence in SrcSpan between class declaration and functions

I have the following code

module Folder1.JP1 where

class C1 a where
    toString :: a -> String

t1 :: String
t1=
   let
        t="test1"
   in t

t2 :: String
t2="test2"

And I noticed an incoherence in the SrcSpan of the Class declaration compared to the function. The ClassDecl for C1 will have a SrcSpan from line 3 column 0 to line 6 column0. The t1 PatBind will start from line 7 column 0 to line 10 column 8. I use the SrcSpan to provide folding regions in EclipseFP, and the extra lines in the class declaration span cause issues. The SrcSpan of the ClassDecl should stop at the end of the last non empty line as the patbinds do.

Thanks!

DataKinds/PolyKinds not supported

I have a use for your parsing module, but I need DataKinds and PolyKinds for it. Do you have any plans to implement these extensions?

ConstraintKinds not fully supported

An HLint user reported: http://code.google.com/p/ndmitchell/issues/detail?id=543

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ConstraintKinds #-}
class Foo a where 

type Bar a
type Bazable a b = (Bar a ~ Maybe b)

baz :: Bazable a b => a -> a
baz = id

Gives: Parse error in type: Bar a ~ Maybe b

The failure only occurs when we have a ~ constraint in a constraint kind. ~ constraints normally work, and constraint kinds normally work, but together HSE explodes.

More graceful handling of unrecognized pragmas

When trying to use hs-gen-iface, I get quite a lot of parse errors on pragmas of big libraries. With vector, I get complaints about {-# INLINE_STREAM sized #-} ("Parse error: sized"), bytestring fails on {-# INLINE CONLIKE size #-} (although that is probably a bug in bytestring itself).

I understand that it's great to parse pragmas, but if the implementation doesn't understand them (like INLINE_STREAM or MINIMAL), I think it's at least decent to keep them in verbatim. I'm thinking of OtherPragmaDecl l String String and OtherPragmaExp l String String, where the first field would be the pragma keyword, and the second the remaining contents of the pragma.

Support qualified record field puns

As described in the GHC user guide, the following syntax is allowed:

f (C {M.a}) = a

which desugars to

f (M.C {M.a = a}) = a

However, HSE fails to parse this syntax:

Prelude Language.Haskell.Exts> parseModuleWithMode defaultParseMode {extensions = [EnableExtension NamedFieldPuns]}  "f (C {M.a}) = a"
ParseFailed (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 1, srcColumn = 10}) "Illegal qualified name"

Dependency on happy

HSE has an implicit dependency on happy for the parser. If happy isn't already installed then cabal install HSE doesn't work, it would be great if this could be fixed. This problem has shown up for real users trying to install both derive and hlint - failing when installing HSE because of the lack of happy.

Related to this deficiency in cabal-install: http://hackage.haskell.org/trac/hackage/ticket/227

GHC vs HSE: List of all extensions handled by GHC but not yet by HSE

Below is a hopefully comprehensive list of the extensions added to GHC that HSE is not yet aware of.

  • MonadComprehensions
  • TraditionalRecordSyntax
  • Safe, Unsafe, Trustworthy

Some of these will have no syntactic impact and can thus be ticked off after having been added to Language.Haskell.Exts.Extension. Those that are syntactic in nature should each be given an issue of their own, with a reference added to the list above. When fixed, remove from list.

I intend to use this list as an evolving comparison to GHC, to keep track of how we're doing.

Ambiguous infix expression involving splice and quasi-quoter

I'm pretty sure the module below loads into ghci but fails to parse regardless of the parse extensions. If you have hsx2hs installed and put {-# OPTIONS_GHC -F -pgmFhsx2hs #-} it will fail.

{-# LANGUAGE TemplateHaskell #-}
module Bug where

import Control.Applicative ((<$>))
import Control.Monad.Reader (ask)
import Language.Haskell.Exts.Syntax as S
import Language.Haskell.TH as TH

getOne = undefined
getEQ = undefined
tName = undefined
siteRecords = undefined

type Site = ()

idTypeName = undefined
typ = undefined
rowTypeName = undefined
tableFieldName = undefined
getEventFnName = undefined

data Rec
    = Row {recDecl :: S.Decl, recIndexTypes :: [String]}
    | Rec {recDecl :: S.Decl} deriving (Eq, Ord, Show)

inferGetByEvent (Row decl@(DataDecl _ _ _ (Ident row@(r:ow)) _ _ _) types) =
      do let getBy = mkName $ getEventFnName decl
         i <- newName "i"
         s <- sigD getBy [t| $(idTypeName decl >>= conT) -> $(typ "Query") $(typ "AppState") (Maybe $(rowTypeName decl >>= conT)) |]
         x <- funD getBy [clause [varP i] (normalB [|getOne . getEQ $(varE i) . $(tableFieldName decl >>= varE) <$> ask|]) []]
         return [s, x]
inferGetByEvent _ = error "inferGetByEvent"

Support MINIMAL pragma

http://ghc.haskell.org/trac/ghc/ticket/7633#comment:28

The MINIMAL pragma takes a boolformula of names, describing which functions are needed in an instance before it is complete:

sigdecl :: { Located (OrdList (LHsDecl RdrName)) }
    : 
    {- ... -}
        -- A minimal complete definition 
    | '{-# MINIMAL' name_boolformula_opt '#-}' 
        { LL $ unitOL (LL $ SigD (MinimalSig $2)) } 

{- ... -}

name_boolformula_opt :: { BooleanFormula (Located RdrName) } 
        : name_boolformula          { $1 } 
        | {- empty -}               { mkTrue } 

name_boolformula :: { BooleanFormula (Located RdrName) } 
        : name_boolformula_and                      { $1 } 
        | name_boolformula_and '|' name_boolformula { mkOr [$1,$3] } 

name_boolformula_and :: { BooleanFormula (Located RdrName) } 
        : name_boolformula_atom                             { $1 } 
        | name_boolformula_atom ',' name_boolformula_and    { mkAnd [$1,$3] } 

name_boolformula_atom :: { BooleanFormula (Located RdrName) } 
        : '(' name_boolformula ')'  { $2 } 
        | name_var                  { mkVar $1 } 

No support for 'chained' do-notation in Haskell98 mode

main :: IO ()
main = do
    if True then return () else do
    return ()
  • GHC: succeeds with Haskell98, fails with Haskell2010. DoAndIfThenElse doesn't influence this, but I suspect it might be the actual culprit.

    /tmp/poc.hs:4:37: Empty 'do' block

  • haskell-src-exts: fails regardless of base language or DoAndIfThenElse:

    Parse error: Last statement in a do-block must be an expression

Fixities not supported for type operators

Should be pretty straightforward to use code similar to expressions.

See http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/data-type-extensions.html#infix-tycons

Fixities may be declared for type constructors, or classes, just as for data constructors. However, one cannot distinguish between the two in a fixity declaration; a fixity declaration sets the fixity for a data constructor and the corresponding type constructor.

Note that in addition to adding an instance of AppFixity, the 'parseType*' functions will need to be changed - currently they do not call applyFixities.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.