我正在尝试做类似于下面的事情,我想在State-Monad的状态不满足特定条件的情况下返回错误消息,可以在不使用lift
和ExceptT
或其他Transformer monad的情况下完成吗?
type Log = State [String] ()
stateCheckDuplicate :: String -> Either String Log
stateCheckDuplicate elem =
Right (do
log <- get
if lookup elem log /= Nothing then Left "Duplicate elements"
else
(put (elem:log)))
1条答案
按热度按时间7dl7o3gd1#
如果我理解
stateCheckDuplicate
应该做什么,你需要stateCheckDuplicate
同构于String -> [String] -> Either String [String]
的类型。然后你的实现看起来像这样:正如你所看到的,没有State,也没有ExceptT,也没有liftXXX。但是可能有一个问题,这个函数很难与其他函数组合。要解决这个问题需要了解你试图做什么。
最新情况:
好的,我想在一个do块中使用它来执行一系列操作,这样状态(或者在本例中是字符串)将在每次操作时更新。然后,这些操作中的每一个又可以使用例如mapM_等来处理。如果State或String-function返回Left部分,我希望带有do块的函数返回Left“Duplicate elements”,否则带有do块的函数将返回完全不同的类型,可能是String(Int,Int)或其他类型。
为了在do-block中使用这个操作,结果类型应该是类
Monad
的示例。您可以为此目的创建自己的类型。但是,比较一下使用变压器会有多容易:
如果你不想要类型别名,你可以这样做: