I've got a quick question. Haskell is throwing the 57 - Undefined variable "f" error
at me and I've no idea why. I'd appreciate it if you could have a look at this.
Code:
eval :: Expr -> Environment -> Float
eval expr env = eval' expr
where
eval' :: Expr-> Float
eval' (Num num) = num
eval' (App app exprs) = foldl1 (f) (map eval' exprs) -- **Line 57**
eval' (Id id) = 5
where
f = getFunctionForApp app -- **f is here**
getFunctionForApp :: String -> (Float->Float->Float)
getFunctionForApp "+" = (+)
getFunctionForApp "-" = (-)
getFunctionForApp "*" = (*)
getFunctionForApp "/" = (/)
getIdVal :: String -> Environment -> Float
getIdVal id ((curId, val):envrs)
|curId == id = val
| otherwise = getIdVal id envrs
Type definition:
data Expr = Num Float | Id String | App String [ Expr ]
deriving (Eq, Ord, Show)
type Environment = [ ( String, Float ) ]
The where block applies only to the case directly before it, not to all cases of the eval'
function. So f
is defined (but not used) in eval' (Id id) = 5
, but it's not in scope in line 57. To fix this you need to move the where block directly after line 57.
Exactly what sepp2k said. In this case, though, I'd prefer simply swapping lines 57 and 58, so the where
is attached to the right equation without splitting the equations for eval'
, that's more readable.
Or don't use f
at all, make it
eval' (App app exprs) = foldl1 (getFunctionOrApp app) (map eval' exprs)
eval' (Id id) = 5
getFunctionOrApp :: String -> (Float -> Float -> Float)
getFunctionOrApp "+" = ...
Moving getFunctionOrApp
(and getIdVal
) to the same-level where
as eval'
, it may even be reasonable to define them at the top level.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With