Reputation: 65
He guys, I have a problem. I have two functions in my Haskell program.
type Env = String -> Int
emptyEnv :: Env
emptyEnv _ = error "Failed"
insertEnv :: String -> Loc -> Env -> Env
insertEnv s loc env = case env s of
(error "Failed") -> (\inp -> (if inp==s then loc else env s))
_ -> env
So my emptyEnv should always give an error message. With the other function insertEnv you can insert elements to Env. But therefore you need to check if Env is empty and this will display an error on screen. Now my question: The code above doesn't work because error "Failed" is not a case of env s in the function insertEnv. Do you have an idea how I handle the error properly so that you can insert elements to env?
Upvotes: 0
Views: 96
Reputation: 13471
We usually handle failing functions in Haskell by them returning a Maybe
type:
type Loc = Int
type Env = String -> Maybe Loc -- Here
emptyEnv :: Env
emptyEnv _ = Nothing
And for insertEnv
we would write:
insertEnv :: String -> Loc -> Env -> Env
insertEnv s loc env inp =
case env inp of
Nothing ->
if s == inp
then Just loc
else Nothing
Just loc' -> Just loc'
Which follows your intended meaning by not making an insert update the Env
. Another possibility for insertEnv
is to "update" the environment:
insertEnv' :: String -> Loc -> Env -> Env
insertEnv' key loc env inKey
| key == inKey = Just loc
| otherwise = env inKey
If you're interested, both versions can be implemented using the First
and Last
wrappers from Data.Monoid
.
import Data.Monoid
type Env' = String -> First Loc -- Choose First or Last here
emptyEnv' :: Env'
emptyEnv' _ = mempty
insertEnv' :: String -> Loc -> Env' -> Env'
insertEnv' s loc env inp =
env inp <>
if s == inp
then pure loc
else mempty
With some environment
env1 = insertEnv' "1" 2 (insertEnv' "1" 1 emptyEnv')
If you pick First
with the above implementation you get
GHCI> env1 "1"
First {getFirst = Just 1}
or with Last
GHCI> env1 "1"
Last {getLast = Just 2}
Upvotes: 3
Reputation: 44634
With the other function
insertEnv
you can insert elements toEnv
. But therefore you need to check ifEnv
is empty.
Why do you need to check if an environment is empty before you insert something into it? An environment containing the variable x
is just a function that, if given the name x
, returns the value to which x
was bound.
insertEnv s loc env = \v -> if v == s then loc else env v
Upvotes: 2