As part of a mini-haskell compiler that I'm writing, I have a function named app
. What I want this function to do is take in these arguments epp (App e1 e2)
. The first step would be to evaluate e1
recursively (epp e1
) and check if the output would be an error. If not then evaluate e2
and then call another function eppVals
to evaluate the outputs of the calls on e1
and e2
which I defined as v1
and v2
respectively.

- 667
- 2
- 12
- 21
-
I expect that it is a matter of indentation. Hunt and remove all tabs in your source file. If the two bindings for `v1` and `v2` line up with pure spaces, it ought to parse. – Daniel Fischer Nov 17 '12 at 00:55
-
@DanielFischer i did that and now i get an `parse error on input v2` – NuNu Nov 17 '12 at 01:04
-
Can you paste the _exact_ source here? Copy from your file, paste, select, Ctrl+K to indent as code. If the two `v`s are in the same column, it must parse. – Daniel Fischer Nov 17 '12 at 01:15
-
@DanielFischer check above. the two `v`s do line up – NuNu Nov 17 '12 at 01:30
-
Today I learned about Ctrl+K. – Gabriella Gonzalez Nov 17 '12 at 01:36
-
1Copied, pasted, filled up with a few dummy definitions: parses and compiles. If it doesn't parse for you, there must be something else wrong with your file. Can you paste it somewhere (http://hpaste.org for example) in its entirety? – Daniel Fischer Nov 17 '12 at 01:36
1 Answers
In your hpaste you have a function appVals
which has been renamed to eppVals
in your question above. This is unhelpful.
Let's look at some types:
epp :: Exp -> Error Val
appVals :: Val -> Val -> Error Val
The error message Couldn't match expected type Val
with actual type Error Val
is trying to tell you that the first parameter to appVals
is expected to have type Val
(see type signature for appVals
) but the actual type of the value you've provided as the first parameter is v1
, defined as epp e1
, which has type Error Val
(see type signature for epp
).
Val
and Error Val
are not the same type. That's your problem.
How to fix it? You need some way of handling the error cases separately from the rest of the computation. If you have implemented the Applicative
or Monad
classes for your Error
type, this is almost certainly what they do.
Edit: You don't include the definition of your Error
, but I expect it looks like this:
data Error a = S a | Error String
Implement a couple of classes for it (you'll need to import Control.Applicative
):
instance Functor Error where
fmap f (S x) = S (f x)
fmap _ (Error s) = Error s
instance Applicative Error where
pure = S
Error s <*> _ = Error s
_ <*> Error s = Error s
S f <*> S x = S (f x)
Now you can rewrite
epp (App e1 e2) = eppVals <$> epp e1 <*> epp e2

- 46,404
- 6
- 118
- 152