2017-01-29 68 views
0

他們,我有一個問題。我在我的Haskell程序中有兩個函數。Haskell:在Haskell中使用錯誤/異常

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 

所以我的emptyEnv應該總是給出錯誤信息。使用其他函數insertEnv,您可以將元素插入Env。但是因此你需要檢查Env是否爲空,並且這會在屏幕上顯示一個錯誤。現在我的問題:上面的代碼不起作用,因爲錯誤「失敗」不是函數insertEnv中的env的情況。你有一個想法如何正確處理錯誤,以便你可以插入元素env?

回答

2

與其他功能insertEnv您可以插入元素到Env。但是,因此您需要檢查Env是否爲空。

爲什麼在插入東西之前需要檢查一下環境是否爲空?包含變量x的環境只是一個函數,如果名稱爲x,則返回值爲x被綁定的值。

insertEnv s loc env = \v -> if v == s then loc else env v 
3

我們通常處理由他們未能在Haskell函數返回一個Maybe類型:

type Loc = Int 
type Env = String -> Maybe Loc -- Here 

emptyEnv :: Env 
emptyEnv _ = Nothing 

而對於insertEnv可以這樣寫:

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' 

通過不使跟隨你的本意插入更新Env。對於insertEnv另一種可能性是「更新」的環境:

insertEnv' :: String -> Loc -> Env -> Env 
insertEnv' key loc env inKey 
    | key == inKey = Just loc 
    | otherwise = env inKey 

如果你有興趣,這兩個版本可以使用FirstLast包裝從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 

對於某些環境

env1 = insertEnv' "1" 2 (insertEnv' "1" 1 emptyEnv') 

如果你選擇First上述實施你

GHCI> env1 "1" 
First {getFirst = Just 1} 

Last

GHCI> env1 "1" 
Last {getLast = Just 2} 
+0

感謝adamse。快速脫離主題。現在我試着用'emptyEnv = \ _->( - 1)'和'insert s loc env = \ inp - >(如果inp == s然後loc else env s)'但現在當我這樣做時'env =插入「x」42(插入「y」17 emptyEnv)'然後'env「y」'它給我-1所以空的Env的值。那裏發生了什麼?它在5分鐘前工作!? –

+0

你想'... else env inp'。 – adamse