假設我想寫一堆函式,比如func0to func9。他們接受相同的輸入,但用它們做不同的事情。但是,所有這些都涉及相同的輸入檢查。例如:
func0 :: Int -> [a] -> Either String a
func0 i lst
| i < 0 || i > length lst = Left "Index Out of Bounds!"
| otherwise = -- does things
檢查索引越界的部分對于每個函式都是相同的,所以我不想為每個函式重復它們。有沒有什么do魔法可以稍微清理一下代碼?提前致謝!
uj5u.com熱心網友回復:
這似乎很容易分解為高階函式:
check :: (Int -> [a] -> Either String a) -> Int -> [a] -> Either String a
check f i as
| i < 0 || i >= length as = Left "Index Out of Bounds!"
| otherwise = f i as
func0 = check myFunc0
func1 = check myFunc1
等等,其中myFunc0etc 是可能具有不同行為的功能部分。
(不清楚他們做了什么,如果他們都只是給出一個Right值,那么你可能想要改變他們,所以他們只是回傳 ana并將包裝Right放在 的otherwise子句中check。但上面允許你Left在其他情況下回傳失敗值如果你需要。)
(我也更改i > length as為i >= length as因為i = length as假設您將i用作索引也會導致崩潰。)
uj5u.com熱心網友回復:
我會將邊界檢查放在索引函式中。像這樣:
(!?) :: [a] -> Int -> Either String a
lst !? i = case drop i lst of
_ | i < 0 -> bad
[] -> bad
a:_ -> Right a
where bad = Left "Index Out of Bounds!"
現在你可以func0在不檢查索引的情況下根據它寫和朋友,如下所示:
func0 :: Num a => Int -> [a] -> Either String a
func0 i lst = do
a <- lst !? (i-1)
a' <- lst !? (i 1)
return (a a')
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/359148.html
標籤:哈斯克尔
