Haskell splitAt函数使用Error Handler

时间:2017-03-14 15:06:10

标签: haskell

我正在尝试在Haskell中编写一个函数,该函数在第n个元素之后的点处将列表拆分为两个。

到目前为止,我有以下代码:

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

如果数字大于列表的长度,或者数字为负,则该函数还应返回错误消息“Bad”。 E.g

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

非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

这就是我实现这个的方法。 Functor实例是为了方便起见,以避免在case ... of函数中使用splitAt之类的内容,并且与Maybe完全相同。由于您的splitAt版本可以返回不同的值,因此您只需使用您发布的where修改示例,因为将模式匹配修改为类似Good (zs',zs'') = ...的内容会引发异常案例a 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

我希望这会有所帮助。如果有什么不清楚,请随时询问。