git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
First work on the Eff monad
commitec2e0e3d72225e75734a8ee98d961d5340ed3b8d authorPhil Freeman <paf31@cantab.net> dateSun 5 Jan 2014, 17:46 (13 years ago) parent9aa9339
8 files changed+91−18
examples/passing/Eff.purs+59 src/Language/PureScript/Kinds.hs+2−1 src/Language/PureScript/Parser/Kinds.hs+5−4 src/Language/PureScript/Parser/Types.hs+4−3 src/Language/PureScript/Pretty/Kinds.hs+9−2 src/Language/PureScript/Pretty/Types.hs+3−1 src/Language/PureScript/TypeChecker/Kinds.hs+8−6 src/Language/PureScript/TypeChecker/Types.hs+1−1
examples/passing/Eff.pursnew file+59
@@ -0,0 +1,59 @@
1+module Kinds where
2+
3+-- Eff Monad
4+
5+foreign import data Eff :: # ! -> * -> *
6+
7+foreign import ret :: forall e a. a -> Eff e a
8+
9+foreign import (>>=) :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
10+
11+type Pure a = forall e. Eff e a
12+
13+foreign import runPure :: forall a. Pure a -> a
14+
15+-- Errors
16+
17+foreign import data Error :: * -> !
18+
19+foreign import throwError :: forall e r. e -> Eff (err :: Error e | r) {}
20+
21+foreign import catchError :: forall e r a. (e -> Eff r a) -> Eff (err :: Error e | r) a -> Eff r a
22+
23+-- State
24+
25+foreign import data State :: * -> !
26+
27+foreign import get :: forall s r. Eff (state :: State s | r) s
28+
29+foreign import set :: forall s r. s -> Eff (state :: State s | r) {}
30+
31+foreign import runState :: forall s r a. s -> Eff (state :: State s | r) a -> Eff r { value :: a, state :: s }
32+
33+-- ST
34+
35+foreign import data ST :: * -> !
36+
37+foreign import data STRef :: * -> * -> *
38+
39+foreign import newSTRef :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
40+
41+foreign import readSTRef :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
42+
43+foreign import modifySTRef :: forall a h r. (a -> a) -> STRef h a -> Eff (st :: ST h | r) {}
44+
45+foreign import runST :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
46+
47+-- Tests
48+
49+test1 = runPure (runState 0 (catchError (\s -> ret 0)
50+ (get >>= \s ->
51+ throwError "Error!" >>= \_ ->
52+ set (s + 1) >>= \_ ->
53+ ret s)))
54+
55+test2 = runPure (runST (
56+ newSTRef 0 >>= \ref ->
57+ modifySTRef (\n -> n + 1) ref >>= \_ ->
58+ readSTRef ref))
59+
src/Language/PureScript/Kinds.hs+2−1
@@ -22,5 +22,6 @@ import Language.PureScript.Unknown
2222data Kind
2323 = KUnknown (Unknown Kind)
2424 | Star
25− | Row
25+ | Bang
26+ | Row Kind
2627 | FunKind Kind Kind deriving (Show, Eq, Data, Typeable)
src/Language/PureScript/Parser/Kinds.hs+5−4
@@ -26,16 +26,17 @@ import qualified Text.Parsec.Expr as P
2626parseStar :: P.Parsec String ParseState Kind
2727parseStar = const Star <$> lexeme (P.char '*')
2828
29−parseRow :: P.Parsec String ParseState Kind
30−parseRow = const Row <$> lexeme (P.char '#')
29+parseBang :: P.Parsec String ParseState Kind
30+parseBang = const Bang <$> lexeme (P.char '!')
3131
3232parseTypeAtom :: P.Parsec String ParseState Kind
3333parseTypeAtom = indented *> P.choice (map P.try
3434 [ parseStar
35− , parseRow
35+ , parseBang
3636 , parens parseKind ])
3737
3838parseKind :: P.Parsec String ParseState Kind
3939parseKind = P.buildExpressionParser operators parseTypeAtom P.<?> "kind"
4040 where
41− operators = [ [ P.Infix (lexeme (P.try (P.string "->")) >> return FunKind) P.AssocRight ] ]
41+ operators = [ [ P.Prefix (lexeme (P.char '#') >> return Row) ]
42+ , [ P.Infix (lexeme (P.try (P.string "->")) >> return FunKind) P.AssocRight ] ]
src/Language/PureScript/Parser/Types.hs+4−3
@@ -69,6 +69,7 @@ parseTypeAtom = indented *> P.choice (map P.try
6969 , parseTypeVariable
7070 , parseTypeConstructor
7171 , parseForAll
72+ , parens parseRow
7273 , parens parseType ])
7374
7475parseAnyType :: P.Parsec String ParseState Type
@@ -90,14 +91,14 @@ parsePolyType = do
9091 unless (isPolyType ty) $ P.unexpected "polymorphic type"
9192 return ty
9293
93−parseNameAndType :: P.Parsec String ParseState (String, Type)
94−parseNameAndType = (,) <$> (indented *> identifier <* indented <* lexeme (P.string "::")) <*> parsePolyType
94+parseNameAndType :: P.Parsec String ParseState t -> P.Parsec String ParseState (String, t)
95+parseNameAndType p = (,) <$> (indented *> identifier <* indented <* lexeme (P.string "::")) <*> p
9596
9697parseRowEnding :: P.Parsec String ParseState Type
9798parseRowEnding = P.option REmpty (TypeVar <$> (lexeme (indented *> P.char '|') *> indented *> identifier))
9899
99100parseRow :: P.Parsec String ParseState Type
100−parseRow = (fromList <$> (commaSep parseNameAndType) <*> parseRowEnding) P.<?> "row"
101+parseRow = (fromList <$> (commaSep $ parseNameAndType parsePolyType) <*> parseRowEnding) P.<?> "row"
101102 where
102103 fromList :: [(String, Type)] -> Type -> Type
103104 fromList [] r = r
src/Language/PureScript/Pretty/Kinds.hs+9−2
@@ -27,10 +27,16 @@ typeLiterals :: Pattern () Kind String
2727typeLiterals = mkPattern match
2828 where
2929 match Star = Just "*"
30− match Row = Just "#"
30+ match Bang = Just "!"
3131 match (KUnknown (Unknown u)) = Just $ 'u' : show u
3232 match _ = Nothing
3333
34+matchRow :: Pattern () Kind ((), Kind)
35+matchRow = mkPattern match
36+ where
37+ match (Row k) = Just ((), k)
38+ match _ = Nothing
39+
3440funKind :: Pattern () Kind (Kind, Kind)
3541funKind = mkPattern match
3642 where
@@ -44,4 +50,5 @@ prettyPrintKind = fromMaybe (error "Incomplete pattern") . pattern matchKind ()
4450 matchKind = buildPrettyPrinter operators (typeLiterals <+> fmap parens matchKind)
4551 operators :: OperatorTable () Kind String
4652 operators =
47− OperatorTable [ [ AssocR funKind $ \arg ret -> arg ++ " -> " ++ ret ] ]
53+ OperatorTable [ [ Wrap matchRow $ \_ k -> "# " ++ k]
54+ , [ AssocR funKind $ \arg ret -> arg ++ " -> " ++ ret ] ]
src/Language/PureScript/Pretty/Types.hs+3−1
@@ -32,13 +32,15 @@ typeLiterals = mkPattern match
3232 match String = Just "String"
3333 match Boolean = Just "Boolean"
3434 match (Array ty) = Just $ "[" ++ prettyPrintType ty ++ "]"
35− match (Object row) = Just $ "{ " ++ prettyPrintRow row ++ " }"
35+ match (Object row) = Just $ "{ " ++ prettyPrintType row ++ " }"
3636 match (TypeVar var) = Just var
3737 match (TypeConstructor ctor) = Just $ show ctor
3838 match (TUnknown (Unknown u)) = Just $ 'u' : show u
3939 match (Skolem s) = Just $ 's' : show s
4040 match (SaturatedTypeSynonym name args) = Just $ show name ++ "<" ++ intercalate "," (map prettyPrintType args) ++ ">"
4141 match (ForAll ident ty) = Just $ "forall " ++ ident ++ ". " ++ prettyPrintType ty
42+ match REmpty = Just $ prettyPrintRow REmpty
43+ match row@(RCons _ _ _) = Just $ prettyPrintRow row
4244 match _ = Nothing
4345
4446prettyPrintRow :: Type -> String
src/Language/PureScript/TypeChecker/Kinds.hs+8−6
@@ -44,7 +44,8 @@ instance Unifiable Kind where
4444 KUnknown u ~~ k = replace u k
4545 k ~~ KUnknown u = replace u k
4646 Star ~~ Star = return ()
47− Row ~~ Row = return ()
47+ Bang ~~ Bang = return ()
48+ Row k1 ~~ Row k2 = k1 ~~ k2
4849 FunKind k1 k2 ~~ FunKind k3 k4 = do
4950 k1 ~~ k3
5051 k2 ~~ k4
@@ -100,7 +101,7 @@ infer (Array t) = do
100101 return Star
101102infer (Object row) = do
102103 k <- infer row
103− k ~~ Row
104+ k ~~ Row Star
104105 return Star
105106infer (Function args ret) = do
106107 ks <- mapM infer args
@@ -127,11 +128,12 @@ infer (ForAll ident ty) = do
127128 k <- fresh
128129 moduleName <- substCurrentModule <$> ask
129130 bindLocalTypeVariables moduleName [(ProperName ident, k)] $ infer ty
130−infer REmpty = return Row
131+infer REmpty = do
132+ k <- fresh
133+ return $ Row k
131134infer (RCons _ ty row) = do
132135 k1 <- infer ty
133136 k2 <- infer row
134− k1 ~~ Star
135− k2 ~~ Row
136− return Row
137+ k2 ~~ Row k1
138+ return $ Row k1
137139infer _ = error "Invalid argument to infer"
src/Language/PureScript/TypeChecker/Types.hs+1−1
@@ -24,7 +24,7 @@ import Data.Maybe (fromMaybe)
2424import Data.Either (lefts, rights)
2525import qualified Data.Data as D
2626import Data.Generics
27− (mkT, something, everywhere, everywhereBut, mkQ, extQ)
27+ (mkT, something, everywhere, everywhereBut, mkQ)
2828
2929import Language.PureScript.Values
3030import Language.PureScript.Types