packages feed

annotated-fix (empty) → 0.1.0.0

raw patch · 5 files changed

+170/−0 lines, 5 filesdep +basedep +recursion-schemessetup-changed

Dependencies added: base, recursion-schemes

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for decorated++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2019, Guerric Chupin++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Guerric Chupin nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ annotated-fix.cabal view
@@ -0,0 +1,31 @@+cabal-version:       >=1.10+-- Initial package description 'decorated.cabal' generated by 'cabal init'.+--   For further documentation, see http://haskell.org/cabal/users-guide/++name:                annotated-fix+version:             0.1.0.0+synopsis:            A fixpoint of a functor that can be annotated+description:         This library exposes a type representing the fixpoint+                     of a functor, with an annotation at every node.+-- bug-reports:+license:             BSD3+license-file:        LICENSE+author:              Guerric Chupin+maintainer:          guerric.chupin@gmail.com+-- copyright:+category:            Data+build-type:          Simple+extra-source-files:  CHANGELOG.md++source-repository head+  type:     git+  location: https://gitlab.com/chupin/annotated-fix.git++library+  exposed-modules:     Data.Functor.Annotated+  -- other-modules:+  -- other-extensions:+  build-depends:       base >=4.9 && <5+                     , recursion-schemes >= 5 && <6+  hs-source-dirs:      src+  default-language:    Haskell2010
+ src/Data/Functor/Annotated.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable,+             FlexibleInstances, TypeFamilies #-}++-- | This modules exposes a type representing the fixpoint of a functor type,+-- paired with an annotation. It exports the recursion-schemes instances for+-- this type and a few specific utility functions.+--+-- = Motivation+--+-- Suppose one has an Abstract Syntax Tree (AST) for the lambda calculus:+--+-- > data Term = Var String | App Term Term | Lam String Term+--+-- Such a type can easily be used with the recursion-schemes library, but it is+-- not always convenient to use this type. It is often the case that one wants+-- to add extra informations to every node of an AST, such as location or type+-- information. In this case, instead of adding those informations as an+-- extra-field to all data constructors, one could prefer to represent terms as+-- a record of a descriptor and the information present at every node, like so:+--+-- > data TermDesc = Var String | App Term Term | Lam String Term+-- > data Term = Term { termDesc :: TermDesc+-- >                  , termTyp  :: Typ+-- >                  , termLoc  :: Loc+-- >                  , ...+-- >                  }+--+-- This library implements this general pattern through the 'Annot' type,+-- representing the fixpoint of a functor type, paired with some annotation. In+-- this setting, the above example would be represented like so:+--+-- > data TermDesc r = Var String | App r r | Lam String r+-- >+-- > data TermAnn = TermAnn { termTyp :: Typ+-- >                        , termLoc :: Loc+-- >                        , ...+-- >                        }+-- >+-- > type Term = Annot TermDesc TermAnn++module Data.Functor.Annotated where++import Data.Functor.Foldable+import GHC.Generics++-- | The fixpoint type of functor @f@, with some annotation @a@.+data Annot f a = Annot a (f (Annot f a))+               deriving( Generic+                       , Functor+                       , Foldable+                       , Traversable+                       )++type instance Base (Annot f a) = f++instance Functor f => Recursive (Annot f a) where+  project = strip++-- ** Annotating and deannotating++-- | Strips one level of annotation+strip :: Annot f a -> f (Annot f a)+strip (Annot _ d) = d++-- | Extracts the annotation+annotation :: Annot f a -> a+annotation (Annot a _) = a++-- | Annotates all the node of a functor's fixpoint value+annotate :: Functor f => (f (Annot f a) -> a) -> Fix f -> Annot f a+annotate = annotateRec++-- | Generalized version of 'annotate' for instances of 'Recursive'+annotateRec :: Recursive t+            => (Base t (Annot (Base t) a) -> a)+            -> t+            -> Annot (Base t) a+annotateRec ann = cata aux+  where aux d = Annot (ann d) d++-- | Strips all annotations+deannotate :: Functor f => Annot f a -> Fix f+deannotate = deannotateCorec++-- | Generalized version of 'deannotate' for instances of 'Corecursive'+deannotateCorec :: Corecursive t => Annot (Base t) a -> t+deannotateCorec = embed . fmap deannotateCorec . strip++-- ** Specific schemes++-- | 'cata'morphism with access to the current annotation+cataAnn :: Functor f => (a -> f b -> b) -> Annot f a -> b+cataAnn fun = paraAnn (\a ffaab -> fun a (fmap snd ffaab))++-- | 'para'morphism with access to the current annotation+paraAnn :: Functor f+        => (a -> f (Annot f a, b) -> b)+        -> Annot f a+        -> b+paraAnn fun ann = para aux ann (annotation ann)+  where aux fafaab a =+          fun a (fmap (\(afa, ab) -> (afa, ab (annotation afa))) fafaab)