4 {-# LANGUAGE OverloadedStrings #-}
5 -- For Show (SomeData a)
6 {-# LANGUAGE UndecidableInstances #-}
8 -- | This module provides the 'Viewer' semantic
9 -- which interprets combinators as human-readable text.
10 -- However there is no wrapping nor indenting.
11 module Symantic.Semantics.Viewer where
13 import Data.Function qualified as Fun
15 import Data.List qualified as List
17 import Numeric.Natural (Natural)
19 import Prelude qualified
21 import Symantic.Semantics.Data
22 import Symantic.Semantics.LetInserter
23 import Symantic.Semantics.Viewer.Fixity
24 import Symantic.Syntaxes.Classes
25 import Symantic.Syntaxes.Derive
29 Viewer :: (ViewerEnv -> ShowS) -> Viewer a
30 ViewerUnifix :: Unifix -> String -> String -> Viewer (a -> b)
31 ViewerInfix :: Infix -> String -> String -> Viewer (a -> b -> c)
32 ViewerApp :: Viewer (b -> a) -> Viewer b -> Viewer a
34 view :: Viewer a -> String
39 { viewerEnvOp = (infixN 0, SideL)
40 , viewerEnvPair = pairParen
41 , viewerEnvLamDepth = 1
45 runView :: Viewer a -> ViewerEnv -> ShowS
46 runView (Viewer v) env = v env
47 runView (ViewerInfix _op name _infixName) _env = showString name
48 runView (ViewerUnifix _op name _unifixName) _env = showString name
49 runView (ViewerApp f x) env =
50 pairViewer env op Fun.$
51 runView f env{viewerEnvOp = (op, SideL)}
53 Fun.. runView x env{viewerEnvOp = (op, SideR)}
57 -- | Unusual, but enables to leverage default definition of methods.
58 type instance Derived Viewer = Viewer
60 instance LiftDerived Viewer where
63 instance IsString (Viewer a) where
64 fromString s = Viewer Fun.$ \_env -> showString s
65 instance Show (Viewer a) where
70 { viewerEnvOp = (infixN p, SideL)
71 , viewerEnvPair = pairParen
72 , viewerEnvLamDepth = 1
74 instance Show (SomeData Viewer a) where
75 showsPrec p (SomeData x) = showsPrec p (derive x :: Viewer a)
77 -- ** Type 'ViewerEnv'
78 data ViewerEnv = ViewerEnv
79 { viewerEnvOp :: (Infix, Side)
80 , viewerEnvPair :: Pair
81 , viewerEnvLamDepth :: Natural
84 pairViewer :: ViewerEnv -> Infix -> ShowS -> ShowS
86 if isPairNeeded (viewerEnvOp env) op
87 then showString o Fun.. s Fun.. showString c
90 (o, c) = viewerEnvPair env
92 instance Abstractable Viewer where
93 lam f = Viewer Fun.$ \env ->
94 pairViewer env op Fun.$
95 let x = showString "x" Fun.. shows (viewerEnvLamDepth env)
98 Fun.. showString " -> "
100 (f (Viewer (\_env -> x)))
102 { viewerEnvOp = (op, SideL)
103 , viewerEnvLamDepth = Prelude.succ (viewerEnvLamDepth env)
107 instance Letable Viewer where
108 let_ x f = Viewer Fun.$ \env ->
109 pairViewer env op Fun.$
110 let l = showString "x" Fun.. shows (viewerEnvLamDepth env)
113 Fun.. showString " = "
117 { viewerEnvOp = (infixN 0, SideL)
118 , viewerEnvLamDepth = Prelude.succ (viewerEnvLamDepth env)
120 Fun.. showString " in "
122 (f (Viewer (\_env -> l)))
124 { viewerEnvOp = (infixN 0, SideL)
125 , viewerEnvLamDepth = Prelude.succ (viewerEnvLamDepth env)
129 instance LetRecable Int Viewer where
130 letRec len f body = Viewer Fun.$ \env ->
132 [ showString "u" Fun.. shows (viewerEnvLamDepth env Prelude.+ Prelude.fromIntegral idx)
133 | idx <- [0 .. len Prelude.- 1]
135 in let self idx = Viewer Fun.$ \_env -> fns List.!! idx
136 in let lvs = List.zipWith (\v idx -> (v, f self idx)) fns [0 .. len Prelude.- 1]
137 in pairViewer env op Fun.$
142 Fun.. showString " = "
146 { viewerEnvOp = (infixN 0, SideL)
147 , viewerEnvLamDepth = Prelude.succ (viewerEnvLamDepth env)
151 Fun.. showString " in "
155 { viewerEnvOp = (infixN 0, SideL)
156 , viewerEnvLamDepth = viewerEnvLamDepth env Prelude.+ Prelude.fromIntegral len
160 instance Abstractable1 Viewer where
161 lam1 f = Viewer Fun.$ \env ->
162 pairViewer env op Fun.$
163 let x = showString "u" Fun.. shows (viewerEnvLamDepth env)
166 Fun.. showString " -> "
168 (f (Viewer (\_env -> x)))
170 { viewerEnvOp = (op, SideL)
171 , viewerEnvLamDepth = Prelude.succ (viewerEnvLamDepth env)
175 instance Instantiable Viewer where
176 ViewerApp (ViewerInfix op _name infixName) x .@ y = Viewer Fun.$ \env ->
177 pairViewer env op Fun.$
178 runView x env{viewerEnvOp = (op, SideL)}
180 Fun.. showString infixName
182 Fun.. runView y env{viewerEnvOp = (op, SideR)}
183 f .@ x = ViewerApp f x
184 instance Unabstractable Viewer where
185 ap = ViewerInfix (infixL 4) "(<*>)" "<*>"
188 (.) = ViewerInfix (infixR 9) "(.)" "."
190 ($) = ViewerInfix (infixR 0) "($)" "$"
191 instance Varable Viewer where
193 instance Anythingable Viewer
194 instance Bottomable Viewer where
196 instance Show c => Constantable c Viewer where
197 constant c = Viewer Fun.$ \_env -> shows c
198 instance Eitherable Viewer where
202 instance Equalable Viewer where
203 equal = ViewerInfix (infixN 4) "(==)" "=="
204 instance Listable Viewer where
205 cons = ViewerInfix (infixR 5) "(:)" ":"
207 instance Maybeable Viewer where
210 instance IfThenElseable Viewer where
211 ifThenElse test ok ko = Viewer Fun.$ \env ->
212 pairViewer env op Fun.$
214 Fun.. runView test env{viewerEnvOp = (op, SideL)}
215 Fun.. showString " then "
216 Fun.. runView ok env{viewerEnvOp = (op, SideL)}
217 Fun.. showString " else "
218 Fun.. runView ko env{viewerEnvOp = (op, SideL)}
223 instance MemoGenLetRecable Viewer where
224 group_normalize :: Locus -> Locus -> VLBindings sem -> ([VLBindings sem], VLBindings sem)
225 memoGenLetRecLocus :: (Locus -> sem a) -> sem a
226 memoGenLetRecLocus f = f
227 memoGenLetRec :: Locus -> MemoKey sem -> sem a -> sem a