2017-03-14 70 views
0

我正在嘗試在Haskell中編寫一個函數,該函數在第n個元素之後的位置將列表拆分爲兩個。Haskell split使用Error Handler的函數

我有下面的代碼至今:

data Err e = Bad|Good e 

splitAt:: Int -> [a] -> Err(([a],[a])) 
splitAt 0 zs = Good(([], zs)) 
splitAt n _ = Bad 

我不知道如何運用錯誤信息給下面的情況:

splitAt n (z:zs) | n > 0 = (z:zs', zs'') where (zs', zs'') = split (n-1) zs 

的功能也應該返回錯誤信息「壞「,如果該數字大於列表的長度,或者數字是負數。例如

splitAt 6 [1,2,3,] = Bad 
splitAt (-3) [1,2,3] = Bad 

任何意見將不勝感激。

+0

爲什麼使用'Err'?這就是「可能」的用途,如果你使用它,你有一個完整的圖書館來幫助你。 – Carcigenicate

+0

我是Haskell的新手,希望練習使用多態類型 – NoahSM1993

+0

哦,好的。只要知道你的Err類型是Haskell的Maybe的最小版本。在「真實代碼」中選擇使用Maybe來代替。 – Carcigenicate

回答

0

這是我如何實現這一點。 Functor實例爲了方便起見,在splitAt函數中避免了case ... of之類的內容,並且與Maybe完全一樣。由於您的splitAt版本可能會返回不同的值,因此您不能簡單地修改您發佈的where的示例,因爲修改模式匹配爲Good (zs',zs'') = ...之類的內容會在返回Bad時引發異常,反之亦然。

data Err e = Bad|Good e deriving (Eq, Show) 

    instance Functor Err where 
    fmap _ Bad  = Bad 
    fmap f (Good a) = Good (f a) 

    splitAt' 0 zs = Good ([],zs) 
    splitAt' n [] = Bad 
    splitAt' n (z:zs) 
    | n > 0  = fmap (\(zs',zs'') -> (z:zs',zs'')) (splitAt' (n-1) zs) 
    | otherwise = Bad 

我希望這會有所幫助。隨意詢問是否有不清楚的地方。