Skip to content

Instantly share code, notes, and snippets.

@glguy
Created July 11, 2018 16:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save glguy/14dc2d453462cd3df875a0caf4d96a28 to your computer and use it in GitHub Desktop.
Save glguy/14dc2d453462cd3df875a0caf4d96a28 to your computer and use it in GitHub Desktop.
{-# Language DeriveDataTypeable #-}
module GHash where
import Data.Generics
data HashSkeleton
= HashSkeleton Constr [HashSkeleton]
| Leaf String -- hash primitive
deriving Show
data Example a
= Variable a String
| Add a (Example a) (Example a)
deriving (Data,Show)
data SourcePos = SourcePos
deriving (Data,Show)
-- | Compute a generic hash skeleton for a value of our AST
ghash :: GenericQ [HashSkeleton]
ghash = ghash' `extQ` ignoreSourcePos
`extQ` hashString
-- | Add ignore cases for the things we want to skip
ignoreSourcePos :: SourcePos -> [HashSkeleton]
ignoreSourcePos _ = []
-- | Special case for a leaf node
hashString :: String -> [HashSkeleton]
hashString str = [Leaf str]
-- | Generically hash a value using its Data instance
ghash' :: GenericQ [HashSkeleton]
ghash' x = [HashSkeleton (toConstr x) (concat (gmapQ ghash x))]
exampleExpr :: Example SourcePos
exampleExpr =
Add SourcePos (Variable SourcePos "A") (Variable SourcePos "B")
{-
>>> ghash exampleExpr
[HashSkeleton Add [HashSkeleton Variable [Leaf "A"],HashSkeleton Variable [Leaf "B"]]]
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment