@@ -0,0 +1,56 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Language.PureScript.CaseDeclarations
4+-- Copyright : (c) Phil Freeman 2013
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- |
12+--
13+-----------------------------------------------------------------------------
14+
15+module Language.PureScript.CaseDeclarations (
16+ desugarCases
17+) where
18+
19+import Data.List (groupBy)
20+import Control.Monad (join, unless)
21+import Control.Monad.Error.Class
22+import Language.PureScript.Names
23+import Language.PureScript.Values
24+import Language.PureScript.Declarations
25+
26+desugarCases :: [Declaration] -> Either String [Declaration]
27+desugarCases = fmap join . mapM toDecls . groupBy inSameGroup
28+
29+inSameGroup :: Declaration -> Declaration -> Bool
30+inSameGroup (ValueDeclaration ident1 _ _) (ValueDeclaration ident2 _ _) = ident1 == ident2
31+inSameGroup _ _ = False
32+
33+toDecls :: [Declaration] -> Either String [Declaration]
34+toDecls d@[ValueDeclaration _ [] _] = return d
35+toDecls ds@(ValueDeclaration ident bs _ : _) = do
36+ let pairs = map toPair ds
37+ unless (all ((== length bs) . length . fst) pairs) $
38+ throwError $ "Argument list lengths differ in declaration " ++ show pairs
39+ return [makeCaseDeclaration ident pairs]
40+toDecls ds = return ds
41+
42+toPair :: Declaration -> ([Binder], Value)
43+toPair (ValueDeclaration _ bs val) = (bs, val)
44+toPair _ = error "Not a value declaration"
45+
46+makeCaseDeclaration :: Ident -> [([Binder], Value)] -> Declaration
47+makeCaseDeclaration ident alternatives =
48+ let
49+ numArgs = length (fst . head $ alternatives)
50+ args = map (('_' :) . show) [1..numArgs]
51+ obj = ObjectLiteral $ map (\arg -> (arg, Var (Qualified global (Ident arg)))) args
52+ objBinders = [ (ObjectBinder (zip args bs), val) | (bs, val) <- alternatives ]
53+ value = foldr (\arg ret -> Abs [Ident arg] ret) (Case obj objBinders) args
54+ in
55+ ValueDeclaration ident [] value
56+