hdiff-0.0.0: executables/Languages/Lines.hs
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeApplications #-}
module Languages.Lines where
import System.IO
import Data.Type.Equality
import Data.Text.Prettyprint.Doc (pretty)
import Data.Text.Prettyprint.Doc.Render.Text
import qualified Data.Text as T
import Generics.MRSOP.Base hiding (Infix)
import Generics.MRSOP.Util
import Generics.MRSOP.TH
import Generics.MRSOP.HDiff.Renderer
import Generics.MRSOP.HDiff.Digest
import Debug.Trace
-----------------------
-- * Parser
-- |We must have a dedicated type 'Line' to make sure
-- we duplicate lines. If we use just @Stmt [String]@
-- the content of the lines will be seen as an opaque type.
-- Opaque values are NOT shared by design.
data Stmt = Stmt [Line]
data Line = Line String
-- |Custom Opaque type
data WKon = WString
-- |And their singletons.
--
-- Note we need instances of Eq1, Show1 and DigestibleHO
data W :: WKon -> * where
W_String :: String -> W WString
instance EqHO W where
eqHO (W_String s) (W_String ss) = s == ss
instance DigestibleHO W where
digestHO (W_String s) = hashStr s
instance ShowHO W where
showHO (W_String s) = s
-- Now we derive the 'Family' instance
-- using 'W' for the constants.
deriveFamilyWithTy [t| W |] [t| Stmt |]
instance RendererHO W where
renderHO (W_String s) = pretty s
instance TestEquality W where
testEquality (W_String _) (W_String _) = Just Refl
parseFile :: String -> IO Stmt
parseFile file =
do program <- readFile file
return (Stmt $ map Line $ lines program)