所以我在Haskell中編寫一個程序,它接收到一個數字n,告訴它返回從第2個素數開始的第n個素數,即第1個素數。該程序的那部分工作,但我不明白的是,如果數字爲0或更少時,程序也會拋出異常。當返回的對象不是字符串時,在Haskell中拋出異常。
pr :: Int -> Int
pr n = (filter(\x -> (getter) == []) [2..]) !! (n-1)
該getter引用了另一個我寫的解決主要問題的方法。它工作正常。
所以我在Haskell中編寫一個程序,它接收到一個數字n,告訴它返回從第2個素數開始的第n個素數,即第1個素數。該程序的那部分工作,但我不明白的是,如果數字爲0或更少時,程序也會拋出異常。當返回的對象不是字符串時,在Haskell中拋出異常。
pr :: Int -> Int
pr n = (filter(\x -> (getter) == []) [2..]) !! (n-1)
該getter引用了另一個我寫的解決主要問題的方法。它工作正常。
默認情況下,如果沒有方程函數在給定參數匹配,你會得到一個運行時錯誤:
fromJust :: Maybe a -> a
fromJust (Just a) = a
-- No case for Nothing
-- fromJust Nothing throws error at runtime
然而,這不適用於數字工作。相反,守衛會做類似的事情:
assertOver0 :: Int ->()
assertOver0 n | n > 0 =()
-- No case for n <= 0
-- assertOver0 (-1) throws error at runtime
雖然這是默認的行爲,這是不好的風格有不完整的圖案/警衛。取而代之的是,明確地產生錯誤,error
或undefined
:
pr n | n >= 0 = filter (null . getter) [2..] !! n
| otherwise = error "Table flip"
-- undefined is just like error, except that error lets you give an error message
-- and undefined doesn't (undefined is more useful when you know it will never
-- be evaluated, and you don't need to give an error message)
-- undefined :: a; error :: String -> a
-- That is, they can take on any type you want them to have, because whatever code
-- is after them will never be executed anyway
-- I took liberties with your definition of pr. Your filtering function didn't use
-- x, so I wrote what I think you meant. I also made it 0-indexed.
-- Prelude.null checks for [], but doesn't incur an Eq constraint, so I replaced
-- (== []) with it.
-- Parens are not needed around the filter, because function application has
-- the highest precedence.
哈斯克爾也有Control.Exception
更復雜的異常處理機制,但你可能不需要在這裏。一般而言,例外和部分功能被忽視(因爲您只能在IO
中處理它們),您應該爭取像Maybe
或Either
這樣的單子。
import Control.Monad
pr n = do guard $ n >= 0 -- guard True = Just(); guard False = Nothing (in this case)
return $ filter (null . getter) [2..] !! n
pr 2 = Just 5
pr (-1) = Nothing
雖然這一切都是不必要的。 (!!)
已經在負指數
ghci> "abc" !! -1
*** Exception: Prelude.!!: negative index
錯誤,所以我們又回到了起點:
pr n = filter (null . getter) [2..] !! n
還有a library重新定義列表的操作(包括(!!)
)是一元,而不是局部的。
進一步的小改進:使用['null'](http://hackage.haskell.org/package/base-4.10.0.0/docs/Prelude.html#v:null)而不是'(== [])' 。更短,並且不會產生'Eq'約束:-) –
@ AntalSpector-Zabusky好抓! – HTNW
在Haskell中,基本上所有東西都只是一個庫函數。因此,它可以很容易地發現與在線搜索引擎。這包括錯誤處理。因此,您可能需要ask Hayoo for error
或for raise
或for throw
。所有這三個存在 - 但raise
只在不同的口味,專門針對特定的圖書館,而throw
和error
是base
,因此「Haskell本身」的一部分。
throw
可以用來生產類型正確的例外,是合適的,如果你可以在某些時候,在你的程序本身,要抓 /分析錯誤。error
只對崩潰的程序最有用,同時在終端上生成(希望)有用的診斷消息,這似乎是你想要的。類型的error
是†,如GHC-8,
error :: HasCallStack => String -> a
的HasCallStack
是最近才加入,讓程序告訴你其中在代碼中出現錯誤。這不會改變您使用該功能的方式;在老版本的GHC的類型只是
error :: String -> a
也就是說,你只要給error
一些錯誤信息,然後用它作爲任何功能,不管是什麼結果類型功能的「結果」實際上應該是。在你的情況,
pr n | n >= 0 = ...
| otherwise = error "Table flip"
如果你給這個函數一個負數,則它將不會給任何實際的結果,但與消息Table flip
程序崩潰,並且在GHC> = 8,也告訴你,這個錯誤發生在pr
之內。
您可能還想知道,其中pr
被稱爲,以實際調試問題。您可以自己使用GHC調用堆棧模擬這樣的:
import GHC.Stack
pr :: HasCallStack => Int -> Int
pr n | n >= 0 = ...
| otherwise = error "Table flip"
請注意,我並不需要改變以任何方式實現,我剛添加的HasCallStack
約束。
error :: forall (r :: RuntimeRep). forall (a :: TYPE r). HasCallStack => [Char] -> a
...不要擔心,這些只是實施細節提升實際上,Haskell語言並沒有如此自然地支持投擲。
文案 其他的答案給你一些很好的文字,所以我要在這裏碼重和輕解釋。如果仍然不清楚的話請做評論,我會盡量填寫它(或者你們任何常規的S.O.回答者都可以打敗我)。
答案
你提出了一個問題,其中n <= 0
輸入無效:
pr :: Int -> Int
pr n = (filter(\x -> (getter) == []) [2..]) !! (n-1)
最簡單的解決方法是匹配模式或保護和手動拋出一個異常:
pr :: Int -> Int
pr n | n <= 0 = error "NO!"
| otherwise = ...
但有時你想要一個非字符串異常,在這種情況下你可能想要Control.Exception
:
{-# LANGUAGE DeriveAnyClass #-}
-- ^^^ This is not just a comment, enables a language extension
import Control.Exception as X
data MyException = ZeroOrNegative
deriving (Exception,Show,Eq,Ord)
-- ^^ N.B. you should derive 'Exception' for
-- types you want to 'throw'
pr n | n <= 0 = X.throw ZeroOrNegative
| otherwise = ...
找到您熟悉的函數的文檔,然後單擊Source按鈕,然後查看它們的功能。一個例子就是'!!' – jberryman
我沒有一個我很熟悉的,因爲這是我第一次使用haskell – Darkhail
去體驗(!!),點擊[here](http://hoogle.haskell .ORG /?hoogle =(!!))。然後[這裏](https://hackage.haskell.org/package/base-4.10.0.0/docs/Prelude.html#v:-33--33-)和[here](https:// hackage。 haskell.org/package/base-4.10.0.0/docs/src/GHC.List.html#%21%21)。和[這裏](https://hackage.haskell.org/package/base-4.10.0.0/docs/src/GHC.List.html#negIndex)。要閱讀更多關於您的主題,請嘗試[this](http://learnyouahaskell.com/syntax-in-functions)並在那裏搜索「警衛」。 –