Difference between revisions of "User:Zzo38/Proposal for more-notation"

From HaskellWiki
Jump to navigation Jump to search
Line 175: Line 175:
   
 
As it might see, they are all written in many places, and the other ones are just written all in one way.
 
As it might see, they are all written in many places, and the other ones are just written all in one way.
  +
<haskell>
 
 
data PExp l = more PExpConstructors l;
 
data PExp l = more PExpConstructors l;
 
instance Annotated PExp where {
 
instance Annotated PExp where {
Line 190: Line 190:
 
return $ fmap convAnn m;
 
return $ fmap convAnn m;
 
};
 
};
  +
</haskell>
   
 
===Magic Set Editor===
 
===Magic Set Editor===

Revision as of 20:20, 9 September 2011

This document is proposal for more-notation in Haskell.

Syntax

Anywhere that a more-notation is allowed (see Uses), you can use the syntax:

  • more [(name_of_enumeration)] more_name {parameters}
  • name_of_enumeration: A name of any type which is an enumeration. It can be another one using more-notation, but it must be able to fully determine it before this more-notation can be fully determined.
  • more_name: A capitalized name. It uses the same namespace as constructors, so you are not allowed to have a constructor of the same name (although it is OK to have types of the that name).
  • parameters: Optional lowercased names. These names are in local scope, and may already exist in this scope, although they do not have to.

A more-declaration is a module-level declaration of this syntax:

  • [ numeric_literal | (enumeration_constructor) ] more_name {parameters} = contents { | contents } ;
  • numeric_literal: It should be a natural number. Omitted is the same as zero. This number is called the "order" of the declaration.
  • enumeration_constructor: A constructor of the enumeration that was specified in the more-notation. If an enumeration is specified, the enumeration constructor is required here. This number is called the "order" of the declaration.
  • parameters: Lowercased names which will be scoped locally to this declaration. The number of parameters must match the number of parameters specified in the more-notation. An unused parameter can be replaced by an underscore.
  • contents: The contents depends on where the more-notation is.

Semantics

In the place where the more-notation is, all contents of more-declarations of that name will be reordered and corrected before being placed in place of the more-notation.

Automatic reordering is overridden by the enumeration constructors or numeric literals in front of more-declarations.

Uses

Do-blocks

A statement in a do-block may be replaced by a more-notation. Semantics of more-declarations becomes as follows:

  • Multiple statements in a single more-declaration stay in that order and consecutive.

Example:

x = (2 *);
main = do {
  x <- return 21;
  more Doing x;
  print x;
};
Doing a = a <- return $ x a;

becomes

x = (2 *);
main = do {
  x <- return 21;
  x <- return $ Main.x x;
  print x; -- results in 42 (the answer to life, the universe, and everything)
};

Case alternatives

An alternative for a case block may be replaced by a more-notation. Semantics of more-declarations becomes as follows:

  • Cases within an order are reordered so that the most specific ones come first.

Example:

X = (_, False, True) -> 1;
X = (True, True, True) -> 2;
X = _ -> 3;
X = (False, True, True) -> 4;
y x = case x of {
  more X;
};

becomes:

y x = case x of {
  (True, True, True) -> 2;
  (False, True, True) -> 4;
  (_, False, True) -> 1;
  _ -> 3;
};

Case guards

Cases can have guards and case alternatives in more-declarations can also have guards that use more-notation. There is no guarantee to the order except:

  • Guards listed in a single more-declaration keep that order.
  • Duplicate guards are removed.
  • Duplicate guard conditions that to not have matching result expressions are errors.
  • You can list guard conditions without the result values; these cause the order to be forced if such guard conditions exist, but does not create them if they do not exist.

Example:

y x = case x of {
  more Cases;
};
Cases = (a, b) | more X a b;
X a b = a > 5 -> b;
X a b = a < 5 -> a;
X a b = a == 5 -> 0;

Datatype declarations

A constructor definition in a data declaration is allowed to be replaced by a more-notation. Semantics of more-declarations becomes as follows:

  • Duplicate constructors are removed.
  • Duplicate constructors that do not match are errors.
  • Multiple constructors in a single more-declaration are guaranteed to keep the order given.

Example:

data T = Zero | more T deriving (Eq);
T = Two | Three | Four;
T = One | Two;

becomes

data T = Zero | One | Two | Three | Four deriving (Eq);

Fields in record syntax

A field in either a data type declaration or in a value construction or update syntax can be replaced by more-notation. Semantics of more-declarations becomes as follows:

  • Duplicate fields are removed.
  • Duplicate fields that do not match are errors.
  • A more-declaration can specify both the type and the value. Types are only used in data type declarations and values only in the other places.

Example:

data Abc = Abc { name_of :: String, more AbcField };
makeAbc :: Abc;
makeAbc = Abc { name_of = "", more AbcField };
AbcField = age_of :: Int = 0;
AbcField = existing :: Bool = True;

becomes

data Abc = Abc { name_of :: String, age_of :: Int, existing :: Bool };
makeAbc :: Abc;
makeAbc = Abc { name_of = "", age_of = 0, existing = True }; 

Lists

A list item can be replaced by a more-notation. Semantics of more-declarations becomes as follows:

  • Multiple items in a single more-declaration stay in that order and consecutive.

Example:

k :: [String];
k = [more K];
1 K = "One";
5 K = "Five";
3 K = "Three";
K = "Zero";

becomes:

k :: [String];
k = ["Zero", "One", "Three", "Five"];

Combining with Template Haskell

Uses in quotations

Manipulation in splices

Types and constructors

* Dec
** MoreCaseD Name MoreOrder [Name] [Match]
** MoreDataD Name MoreOrder [Name] [Con]
** MoreDoD Name MoreOrder [Name] [Stmt]
** MoreListD Name MoreOrder [Name] [Exp]
** MoreRecD Name MoreOrder [Name] [MoreField]
* Info
** MoreI Int MoreMode Name [Dec]
* MoreField = (Name, Maybe StrictType, Maybe Exp)
* MoreMode
** MoreCase
** MoreData
** MoreDo
** MoreList
** MoreRec Bool Bool
* MoreOrder
** NoOrder
** NamedOrder Name
** NumericOrder Int

Purpose to use more-notation

haskell-src-exts

In the ParseSyntax.hs file, everything has to be defined multiple times in different places, and in a common way. Using more-notation with Template Haskell could fix that. You could even put different extensions in different files and then combine them into one file.

data PExp l
    = Var l (QName l)                       -- ^ variable
    | IPVar l (IPName l)                    -- ^ implicit parameter variable
    | Con l (QName l)                       -- ^ data constructor
    | Lit l (Literal l)                     -- ^ literal constant
{- ... -}
instance Annotated PExp where
    ann e = case e of
        Var l qn        -> l
        IPVar l ipn     -> l
        Con l qn        -> l
        Lit l lit       -> l
{- ... -}
   amap f e = case e of
       Var l qn                -> Var   (f l) qn
       IPVar l ipn             -> IPVar (f l) ipn
       Con l qn                -> Con   (f l) qn
       Lit l lit               -> Lit   (f l) lit

As it might see, they are all written in many places, and the other ones are just written all in one way.

 data PExp l = more PExpConstructors l;
 instance Annotated PExp where {
   ann e = case e of more PExpAnnCases;
   amap f e = case e of more PExpAmapCases;
 };
 let {
   convAnn :: Dec -> Dec;
   convAnn (MoreDataD _ _ _ c) = MoreCaseD ''PExpAnnCases NoOrder 'l $ fmap convAnn1 c;
   convAnn1 :: Con -> Match;
   convAnn1 (NormalC n t) = Match (ConP n $ (VarP 'l) : fmap (const WildP) (tail t)) (VarE 'l) [];
 } in do {
   MoreI _ _ _ m <- reify ''PExpConstructors;
   return $ fmap convAnn m;
 };

Magic Set Editor

Extensibility

Literate programming