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 module Symantic.Semantics.Viewer where
12 import Data.Function qualified as Fun
14 import Numeric.Natural (Natural)
15 import Prelude qualified
18 import Symantic.Semantics.Data
19 import Symantic.Semantics.Viewer.Fixity
20 import Symantic.Syntaxes.Classes
21 import Symantic.Syntaxes.Derive
25 Viewer :: (ViewerEnv -> ShowS) -> Viewer a
26 ViewerUnifix :: Unifix -> String -> String -> Viewer (a -> b)
27 ViewerInfix :: Infix -> String -> String -> Viewer (a -> b -> c)
28 ViewerApp :: Viewer (b -> a) -> Viewer b -> Viewer a
30 view :: Viewer a -> ViewerEnv -> ShowS
31 view (Viewer v) env = v env
32 view (ViewerInfix _op name _infixName) _env = showString name
33 view (ViewerUnifix _op name _unifixName) _env = showString name
34 view (ViewerApp f x) env =
35 pairViewer env op Fun.$
36 view f env{viewerEnvOp = (op, SideL)}
38 Fun.. view x env{viewerEnvOp = (op, SideR)}
42 -- | Unusual, but enables to leverage default definition of methods.
43 type instance Derived Viewer = Viewer
45 instance LiftDerived Viewer where
48 instance IsString (Viewer a) where
49 fromString s = Viewer Fun.$ \_env -> showString s
50 instance Show (Viewer a) where
54 { viewerEnvOp = (infixN p, SideL)
55 , viewerEnvPair = pairParen
56 , viewerEnvLamDepth = 1
59 instance Show (SomeData Viewer a) where
60 showsPrec p (SomeData x) = showsPrec p (derive x :: Viewer a)
62 -- ** Type 'ViewerEnv'
63 data ViewerEnv = ViewerEnv
64 { viewerEnvOp :: (Infix, Side)
65 , viewerEnvPair :: Pair
66 , viewerEnvLamDepth :: Natural
69 pairViewer :: ViewerEnv -> Infix -> ShowS -> ShowS
71 if isPairNeeded (viewerEnvOp env) op
72 then showString o Fun.. s Fun.. showString c
75 (o, c) = viewerEnvPair env
77 instance Abstractable Viewer where
78 lam f = Viewer Fun.$ \env ->
79 pairViewer env op Fun.$
80 let x = showString "x" Fun.. shows (viewerEnvLamDepth env)
83 Fun.. showString " -> "
85 (f (Viewer (\_env -> x)))
87 { viewerEnvOp = (op, SideL)
88 , viewerEnvLamDepth = Prelude.succ (viewerEnvLamDepth env)
92 instance Abstractable1 Viewer where
93 lam1 f = Viewer Fun.$ \env ->
94 pairViewer env op Fun.$
95 let x = showString "u" Fun.. shows (viewerEnvLamDepth env)
98 Fun.. showString " -> "
100 (f (Viewer (\_env -> x)))
102 { viewerEnvOp = (op, SideL)
103 , viewerEnvLamDepth = Prelude.succ (viewerEnvLamDepth env)
107 instance Instantiable Viewer where
108 ViewerInfix op _name infixName .@ ViewerApp x y = Viewer Fun.$ \env ->
109 pairViewer env op Fun.$
110 view x env{viewerEnvOp = (op, SideL)}
112 Fun.. showString infixName
114 Fun.. view y env{viewerEnvOp = (op, SideR)}
115 ViewerInfix op name _infixName .@ x = Viewer Fun.$ \env ->
116 showParen Prelude.True Fun.$
117 view x env{viewerEnvOp = (op, SideL)}
119 Fun.. showString name
120 f .@ x = ViewerApp f x
121 instance Unabstractable Viewer where
122 ap = ViewerInfix (infixL 4) "(<*>)" "<*>"
125 (.) = ViewerInfix (infixR 9) "(.)" "."
127 ($) = ViewerInfix (infixR 0) "($)" "$"
128 instance Varable Viewer where
130 instance Anythingable Viewer
131 instance Bottomable Viewer where
133 instance Show c => Constantable c Viewer where
134 constant c = Viewer Fun.$ \_env -> shows c
135 instance Eitherable Viewer where
139 instance Equalable Viewer where
140 equal = ViewerInfix (infixN 4) "(==)" "=="
141 instance Listable Viewer where
142 cons = ViewerInfix (infixR 5) "(:)" ":"
144 instance Maybeable Viewer where
147 instance IfThenElseable Viewer where
148 ifThenElse test ok ko = Viewer Fun.$ \env ->
149 pairViewer env op Fun.$
151 Fun.. view test env{viewerEnvOp = (op, SideL)}
152 Fun.. showString "then"
153 Fun.. view ok env{viewerEnvOp = (op, SideL)}
154 Fun.. showString "else"
155 Fun.. view ko env{viewerEnvOp = (op, SideL)}