1-----------------------------------------------------------------------------
3-- Module : Language.PureScript.CaseDeclarations
4-- Copyright : (c) Phil Freeman 2013
7-- Maintainer : Phil Freeman <paf31@cantab.net>
8-- Stability : experimental
13-----------------------------------------------------------------------------
15module Language.PureScript.CaseDeclarations (
19import Data.List (groupBy)
20import Control.Monad (join, unless)
21import Control.Monad.Error.Class
23import Language.PureScript.Names
24import Language.PureScript.Values
25import Language.PureScript.Declarations
26import Language.PureScript.Scope
28desugarCases :: [Declaration] -> Either String [Declaration]
29desugarCases = fmap join . mapM toDecls . groupBy inSameGroup
31inSameGroup :: Declaration -> Declaration -> Bool
32inSameGroup (ValueDeclaration ident1 _ _ _) (ValueDeclaration ident2 _ _ _) = ident1 == ident2
33inSameGroup _ _ = False
35toDecls :: [Declaration] -> Either String [Declaration]
36toDecls d@[ValueDeclaration _ [] Nothing _] = return d
37toDecls ds@(ValueDeclaration ident bs _ _ : _) = do
38 let tuples = map toTuple ds
39 unless (all ((== map length bs) . map length . fst) tuples) $
40 throwError $ "Argument list lengths differ in declaration " ++ show ident
41 return [makeCaseDeclaration ident tuples]
44toTuple :: Declaration -> ([[Binder]], (Maybe Guard, Value))
45toTuple (ValueDeclaration _ bs g val) = (bs, (g, val))
46toTuple _ = error "Not a value declaration"
48makeCaseDeclaration :: Ident -> [([[Binder]], (Maybe Guard, Value))] -> Declaration
49makeCaseDeclaration ident alternatives =
51 argPattern = map length . fst . head $ alternatives
52 args = take (sum argPattern) $ unusedNames (ident, alternatives)
53 vars = map (\arg -> Var (Qualified global arg)) args
54 binders = [ (join bs, g, val) | (bs, (g, val)) <- alternatives ]
55 value = foldr (\args' ret -> Abs args' ret) (Case vars binders) (rearrange argPattern args)
57 ValueDeclaration ident [] Nothing value
59rearrange :: [Int] -> [a] -> [[a]]
61rearrange (n:ns) xs = take n xs : rearrange ns (drop n xs)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list