[Allow the usage of "undefined" in I/O examples as a wildcard
tobias@goedderz.info**20150213102412
 Ignore-this: 5c8e31939f80e395830beb342306ca8d
] hunk ./src/Igor2/Data/Rules.hs 4
-    Rule, mkRule, rule, rhs, lhs, ithArg, butIthArg, butIthArgs,
+    Rule, rule, rhs, lhs, ithArg, butIthArg, butIthArgs,
hunk ./src/Igor2/Data/Rules.hs 47
+import qualified Language.Haskell.TH as TH
+
+import qualified Control.Monad.State as CMState
+import qualified Data.Set
hunk ./src/Igor2/Data/Rules.hs 65
-mkRule (UnGuardEq ls rs) = rule ls rs
+mkRule (UnGuardEq lhs rhs) = rule lhs . fst $
+    CMState.runState (undefinedToWildcard rhs) newRenameState
hunk ./src/Igor2/Data/Rules.hs 68
+mkRules :: [Equation] -> Rules
hunk ./src/Igor2/Data/Rules.hs 71
+-- Contains a set of used names and a counter to index the next variable
+type RenameState = (Data.Set.Set Name, Int)
+type RenameStateMonad = CMState.State RenameState
+newRenameState = (Data.Set.empty, 0)
+
+-- Replace all occurences of "undefined" by wildcards, each with a different
+-- name.
+undefinedToWildcard :: TExp -> RenameStateMonad TExp
+undefinedToWildcard rhs = do
+    rhs' <- renameVars rhs
+    return rhs'
+  where
+    -- Given a variable named undefined, make sure it has a unique name and
+    -- convert it to a wildcard. Leave everything else as-is.
+    renameVars (TVarE name type') | "undefined" == (TH.nameBase name) =
+        do newname <- makeUniqueNameFrom name
+           return $ TWildE newname type'
+    renameVars t = fmap (root t) (mapM renameVars (subterms t))
+    indexName name i = (mkName (show name ++ show i), Just i)
+    -- If possible, return name. If it's already used, append the next free
+    -- index to it. In any case, add the returned name to the State Set of used
+    -- names. Increase the State Int counter if appropriate.
+    makeUniqueNameFrom :: Name -> RenameStateMonad Name
+    makeUniqueNameFrom name = do
+        (usedNames, counter) <- get
+        let newNames = (name, Nothing) : map (indexName name) [counter..]
+        let isUnused name = not (Data.Set.member name usedNames)
+        let (newName, usedCounter) = head $ filter (isUnused . fst) $ newNames
+        put (Data.Set.insert newName usedNames, fromMaybe counter usedCounter)
+        return newName
+
conflictor [
hunk ./src/Syntax/Context.hs 127
-    ,('True,    conT ''Bool )
-    ,('False,   conT ''Bool )
-    ,('Just,    arrowT [varT "a", appT (conT ''Maybe) (varT "a")])
-    ,('Nothing, appT (conT ''Maybe) (varT "a") )
-    ,('Left,    arrowT [varT "a", foldAppT (conT ''Either) [varT "a", varT "b"]])
-    ,('Right,   arrowT [varT "b", foldAppT (conT ''Either) [varT "a", varT "b"]])
+    ,('True,    boolCon)
+    ,('False,   boolCon)
+    ,('Just,    arrowT [varT "a", appT maybeCon (varT "a")])
+    ,('Nothing, appT maybeCon (varT "a") )
+    ,('Left,    arrowT [varT "a", foldAppT eitherCon [varT "a", varT "b"]])
+    ,('Right,   arrowT [varT "b", foldAppT eitherCon [varT "a", varT "b"]])
]
:
hunk ./src/Syntax/Context.hs 129
+    ,('undefined, forallT ["a"] [] (varT "a"))
hunk ./src/Syntax/Type.hs 141
-forallT vs ps t = fixType $ ForallT (map mkName vs)(map (uncurry mkPred) ps) t
+forallT :: [String] -> [(Name, String)] -> Type -> Type
+forallT vs ps t = fixType $ ForallT (map mkName vs) (map (uncurry mkPred) ps) t