-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtaglessfinal.hs
More file actions
67 lines (49 loc) · 1.37 KB
/
Copy pathtaglessfinal.hs
File metadata and controls
67 lines (49 loc) · 1.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
{-# OPTIONS_GHC -W #-}
module TaglessFinal where
import Text.Printf (printf)
-- our first language
class Algebra t where
lit :: Int -> t
add :: t -> t -> t
instance Algebra Int where
lit = id
add = (+)
genAST :: Algebra t => t
genAST = add (add (lit 1) (lit 2)) (add (lit 3) (lit 4))
testLang1 :: Int
testLang1 = genAST
-- extend the language with mul
class Algebra t => MulAlgebra t where
mul :: t -> t -> t
instance MulAlgebra Int where
mul = (*)
genAST' :: MulAlgebra t => t
genAST' = mul (add (lit 1) (lit 2)) (lit 4)
testLang2 :: Int
testLang2 = genAST'
-- extend a pretty printer
instance Algebra String where
lit = show
add = printf "( %s + %s )"
instance MulAlgebra String where
mul = printf "( %s * %s )"
testLang1' :: String
testLang1' = genAST
testLang2' :: String
testLang2' = genAST'
-- The implementation above has the problem that for each representation type 't'.
-- We can write only one interpreter
-- For example, the code below won't compile due to duplicated instance
--
-- instance Algebra String where
-- lit = show
-- add = printf "(%s+%s)"
--
-- I guess we can use proxy type
newtype Proxy a t = Proxy t
instance Show t => Show (Proxy a t) where
show (Proxy t) = show t
data P
instance Algebra (Proxy P String) where
lit i = Proxy (show i)
add (Proxy s1) (Proxy s2) = Proxy $ "(" ++ s1 ++ "+" ++ s2 ++ ")"