
Ben Franksen wrote:
Ok, it seems I have a version that does what I want. It is not very elegant, I have to manually wrap/unwrap the ErrorT stuff just for the Val case, but at least it seems to work. Here it goes:
eval (Var x) = Eval $ ErrorT $ do env <- get v <- case M.lookup x env of Just v -> return v Nothing -> do warning ("reference to undefined variable " ++ show x) let v = Data "" modify (M.insert x v) return v return (Right v)
warning s = tell $ ["Warning: " ++ s]
While this works for simple var=constant declarations, it breaks down again as soon as I add lambdas and application. Same symptoms as before: eval loops; and it works again if I remove the ErrorT (but then I get a pattern match failure if I apply a non-function which is of course what I wanted to avoid with the ErrorT). This is maddening! There must be some way to get mutual recursion to work while still allowing for clean handling of failure. What galls me the most is that it is so unpredictable whether the program will terminate with a given input or not. (The code is attached.) Cheers Ben