1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE ImplicitPrelude #-}
5 {-# LANGUAGE LambdaCase #-}
6 {-# LANGUAGE MultiParamTypeClasses #-}
7 {-# LANGUAGE OverloadedStrings #-}
8 {-# LANGUAGE PatternSynonyms #-}
9 {-# LANGUAGE ScopedTypeVariables #-}
10 {-# LANGUAGE TypeApplications #-}
11 {-# LANGUAGE TypeFamilies #-}
12 {-# LANGUAGE UndecidableInstances #-} -- For Show (SomeData a)
13 module Symantic.Typed.View where
18 import qualified Data.Function as Fun
19 import qualified Prelude
21 import Symantic.Typed.Fixity
22 import Symantic.Typed.Lang
23 import Symantic.Typed.Data
24 import Symantic.Typed.Derive
27 View :: (ViewEnv -> ShowS) -> View a
28 ViewUnifix :: Unifix -> String -> String -> View (a -> b)
29 ViewInfix :: Infix -> String -> String -> View (a -> b -> c)
30 ViewApp :: View (b -> a) -> View b -> View a
32 runView :: View a -> ViewEnv -> ShowS
33 runView (View v) env = v env
34 runView (ViewInfix _op name _infixName) _env = showString name
35 runView (ViewUnifix _op name _unifixName) _env = showString name
36 runView (ViewApp f x) env =
38 runView f env{viewEnv_op = (op, SideL) } Fun..
40 runView x env{viewEnv_op = (op, SideR) }
43 -- | Unusual, but enables to leverage default definition of methods.
44 type instance Derived View = View
45 instance LiftDerived View where
48 instance IsString (View a) where
49 fromString s = View Fun.$ \_env -> showString s
50 instance Show (View a) where
51 showsPrec p = (`runView` ViewEnv
52 { viewEnv_op = (infixN p, SideL)
53 , viewEnv_pair = pairParen
54 , viewEnv_lamDepth = 1
56 instance Show (SomeData View a) where
57 showsPrec p (SomeData x) = showsPrec p (derive x :: View a)
61 { viewEnv_op :: (Infix, Side)
62 , viewEnv_pair :: Pair
63 , viewEnv_lamDepth :: Int
66 pairView :: ViewEnv -> Infix -> ShowS -> ShowS
68 if isPairNeeded (viewEnv_op env) op
69 then showString o Fun.. s Fun.. showString c
71 where (o,c) = viewEnv_pair env
73 instance Abstractable View where
76 lam1 f = viewLam "u" f
77 ViewInfix op _name infixName .@ ViewApp x y = View Fun.$ \env ->
79 runView x env{viewEnv_op=(op, SideL)} Fun..
80 showString " " Fun.. showString infixName Fun.. showString " " Fun..
81 runView y env{viewEnv_op=(op, SideR)}
82 ViewInfix op name _infixName .@ x = View Fun.$ \env ->
83 showParen Prelude.True Fun.$
84 runView x env{viewEnv_op=(op, SideL)} Fun..
85 showString " " Fun.. showString name
87 viewLam :: String -> (View a -> View b) -> View (a -> b)
88 viewLam varPrefix f = View Fun.$ \env ->
90 let x = showString varPrefix Fun..
91 showsPrec 0 (viewEnv_lamDepth env) in
92 -- showString "Lam1 (" .
93 showString "\\" Fun.. x Fun.. showString " -> " Fun..
94 runView (f (View (\_env -> x))) env
95 { viewEnv_op = (op, SideL)
96 , viewEnv_lamDepth = Prelude.succ (viewEnv_lamDepth env)
101 instance Anythingable View
102 instance Bottomable View where
104 instance Show c => Constantable c View where
105 constant c = View Fun.$ \_env -> shows c
106 instance Eitherable View where
109 instance Equalable View where
110 equal = ViewInfix (infixN 4) "(==)" "=="
111 instance Listable View where
112 cons = ViewInfix (infixR 5) "(:)" ":"
114 instance Maybeable View where