-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpda.hs
More file actions
68 lines (51 loc) · 1.91 KB
/
pda.hs
File metadata and controls
68 lines (51 loc) · 1.91 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
68
type Stack = String
newtype PDA a = P(Stack -> [(a, Stack)])
app :: PDA a -> Stack -> [(a,Stack)]
app (P p) s = p s
instance Functor PDA where
--fmap :: (a -> b) -> PDA a -> PDA b
fmap f p = P(\s -> case app p s of
[] -> []
[(v,out)] -> [(f v,out)])
instance Applicative PDA where
--pure :: a -> PDA a
pure x = P(\s -> [(x,s)])
-- <*> :: PDA (a -> b) -> PDA a -> PDA b
pf <*> px = P(\s -> case app pf s of
[] -> []
[(f,s')] -> app (fmap f px) s')
instance Monad PDA where
-- >>=:: PDA a -> (a -> PDA b) -> PDA b
p >>= f = P(\s -> case app p s of
[] -> []
[(v,s')] -> app (f v) s')
pop :: PDA Char
pop = P(\s-> case s of
[] -> []
(x:xs) -> [(x,xs)])
push :: PDA ()
push = P(\s-> [((), '(':s)])
balance :: String -> PDA Bool
balance [] = P(\s -> case s of
[] -> [(True,s)])
_ -> [(False,s)]
balance ('(':xs) = do push
balance xs
balance (')':xs) = P(\s -> case app pop s
[] -> [(False,xs)]
[s,out] -> )
def :: String -> PDA String
def [] = pure []
def (x:xs) = (def xs) >>= (\vs -> if x == ')' then (push >>= (\v -> return (')':vs))) else (pop >>= (\v -> return ('(':vs))))
def' :: String -> PDA String
def' [] = pure []
def' (x:xs) = do vs <- def' xs
if x == ')' then do push
return (')':vs)
else do pop
return ('(':vs)
exec :: String -> IO ()
exec xs = case app (balance xs) [] of
[(True,"")] -> putStr ("Correct" ++ "\n")
[(True,s)] -> putStr ("Fail :" ++ s ++ "\n")
[(False,s)] -> putStr ("Fail" ++ "\n")