Basically, you have two possibilities:
Something like this:
getEnv ((Func
(RetTypeType t)
(Ident fname) _ _)
:fs)
= (\x -> if x == fname then t else getEnv fs)
or you can use pattern guards:
getEnv (h:fs)
| Func a b _ _ <- h,
Rectype t <- a,
Ident fname <- b
= (\x -> if x == fname then t else getEnv fs)
You could furthermore avoid the lambda:
getEnv (h:fs) x
| Func a b _ _ <- h,
Rectype t <- a,
Ident fname <- b
= if x == fname then t else getEnv fs
The downside with "open" pattern guards may be that the compiler cannot decide anymore whether your patterns are exhaustive.
As @leftaroundabout points out, we can put it even more clearly thus:
getEnv (h:fs) x
| Func a b _ _ <- h,
Rectype t <- a,
Ident fname <- b,
x == fname = t
| otherwise = getEnv fs
This will also let the compiler know that all possible forms of the head of the list are covered, so this I'd term the most preferred way to do it.