了解do块中的保护功能

时间:2019-08-06 14:04:04

标签: haskell functional-programming

我有以下类型:

newtype Rep f a = Rep { runRep :: String -> f (String, a) }

类型Rep f a是有状态计算,将String作为初始状态,并产生(String, a)作为计算结果。计算结果包装在函子f中。

Rep的monad实例如下:

instance Monad f => Monad (Rep f) where 
   return x = pure x 
   Rep a >>= f = Rep $ \s -> do
    (s', xa) <- a s
    let (Rep f') = f xa
    (s'', xf) <- f' s'
    pure (s'', xf)

Rep的替代实例如下:

instance (Monad f, Alternative f) => Alternative (Rep f) where 
    empty = Rep (const empty)
    Rep a <|> Rep b = Rep $ \s -> a s <|> b s

我还具有以下功能:

readCharacter :: (Alternative f, Monad f) => Rep f Char
readCharacter = Rep $ \s -> case s of
[] -> empty
(x:xs) -> pure (xs,x)

以上函数采用状态,如果状态为空列表,则返回empty。如果状态不是空列表,则返回一个元组,其中第一个元素为修改后的状态,第二个元素为Char,包装在函子f中。

我还具有以下功能和数据类型:

data Res = Nil | Character Char | Cop Res Res | Special [Res]

findmatch :: (Monad f, Alternative f) => String -> Rep f Res

findmatch (cs) = do
   x <- readCharacter
   guard (x `elem` cs)
   pure (Character x)

我无法理解上述功能的工作原理。在我看来,对于字符串cs中的每个字符,都会调用readCharacter函数。如果readCharacter返回的字符是字符串cs的元素,则表达式将求值为true。假设函子fMaybe-则guard (True)将返回Just (),然后返回pure (Character x)

但是,我不确定当保护表达式的值为False时会发生什么。例如,假设函子是Maybe,则guard False将返回Nothing。如果Nothing返回了guard False,是否整个do block将返回Nothing?任何见解都会受到赞赏。

0 个答案:

没有答案