Haskell中的`guard` not guards可以用来为`Left`指定特定的消息吗?

fafcakar  于 9个月前  发布在  其他
关注(0)|答案(2)|浏览(71)

RIO-Prelude中的guard函数是否提供了任何方法来决定消息的内容,如果它失败了Either-Monad?使得例如

somefun :: Either String Int
somefun =  do guard (4+2 == 8); return 2

将返回Left someContent,其中someContent是以某种方式指定给guard的字符串。
根据文档,我还没有找到任何方法,但是如果它存在的话,我很乐意知道它,因为guard可能是避免嵌套if-语句的好方法。

d8tt03nd

d8tt03nd1#

这听起来更像是whenunless的工作:

somefun :: Either String Int
somefun = do
   unless (4+2 == 8) $ Left somecontent
   return 2

实际上我更愿意写when (4+2 /= 8) $ Left somecontent

t30tvxxf

t30tvxxf2#

如果条件失败,guard将与empty一起工作,所以不。您应该使用fail,从而创建一些允许添加失败消息的guard
因此,您可以使用:

{-# LANGUAGE FlexibleInstances #-}

instance MonadFail (Either String) where
    fail = Left

guard' :: MonadFail m => String -> Bool -> m ()
guard' msg = go
  where go False = fail msg
        go True = pure ()

所以你失败了:

somefun :: Either String Int
somefun =  do guard' "arithmetic error" (4+2 == 8); return 2

实际上,我很惊讶地发现Either String不是MonadFail的示例(感谢@JosephSible注意到这一点)。

相关问题