【问题标题】:Haskell splitAt function using Error HandlerHaskell splitAt 函数使用错误处理程序
【发布时间】:2017-03-14 15:06:09
【问题描述】:

我正在尝试在 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”。例如

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

任何建议将不胜感激。

【问题讨论】:

  • 为什么使用Err?这就是 Maybe 的用途,如果你使用它,你有一个完整的库可以帮助你。
  • 我是 Haskell 新手,希望练习使用多态类型
  • 哦,好的。只要知道你的 Err 类型是 Haskell 的 Maybe 的最小版本。在“真实代码”中选择使用 Maybe 代替。
  • 您想在 n 为负数且 n 大于数组长度时返回错误,对吗?所以你可以考虑这些情况来加星

标签: haskell


【解决方案1】:

这就是我将如何实现它。 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

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

【讨论】:

    猜你喜欢
    • 2021-12-01
    • 2016-03-06
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多