The

问题描述 投票:0回答:1

我得到了以下代码

 newtype Parser a = Parser { parse :: String -> Maybe (a,String) }

   instance Applicative Parser where
   pure a = Parser $ \s -> Just (a,s)
   f <*> a = Parser $ \s ->
     case parse f s of
       Just (g,s') -> parse (fmap g a) s'
       Nothing -> Nothing

    instance Alternative Parser where
      empty = Parser $ \s -> Nothing
      l <|> r = Parser $ \s -> parse l s <|> parse r s

    satisfy :: (Char -> Bool) -> Parser Char
    satisfy p = Parser f
       where f [] = Nothing
             f (x:xs) = if p x then Just (x,xs) else Nothing

    ws :: Parser ()
    ws = pure () <* many (satisfy isSpace)

我知道ws解析器会删除前导空格。但是我需要一个解释,说明它是如何完成的。我不了解<*语法(我知道<*>)。可以帮助我理解语法以及它为什么起作用吗?

haskell functor applicative
1个回答
0
投票

没有恐惧!当我们经过小步骤并查看它将我们引向何方时,这很容易。下次,请尝试自己做。

[(<*) = liftA2 const(<*) = liftA2 const,所以

liftA2 f x = (<*>) (fmap f x)

((带有适用性表示法;以了解其用途。在以上链接中也列举了适用性法律。)

所以它执行liftA2 f x = (<*>) (fmap f x)的操作,除了它返回的计算值始终为ws :: Parser () ws = pure () <* many (satisfy isSpace) = {- (<*) = liftA2 const -} liftA2 const (pure ()) (many $ satisfy isSpace) = {- liftA2 f x = (<*>) (fmap f x) -} fmap const (pure ()) <*> many (satisfy isSpace) = {- by Applicative laws -} (pure const <*> pure ()) <*> many (satisfy isSpace) = {- by homomorphism law of Applicatives -} pure (const ()) <*> many (satisfy isSpace) = {- with Applicative Do -} do { f <- pure (const ()) ; r <- many (satisfy isSpace) ; pure (f r) } = do { r <- many (satisfy isSpace) ; pure (const () r) } = do { _ <- many (satisfy isSpace) ; pure () } = do { many (satisfy isSpace) ; pure () } = {- Monad Comprehension illustration -} [ () | _ <- many (satisfy isSpace) ]

在纯函数中,many (satisfy isSpace)将完全忽略其第二个参数。我们可以将其称为(),它不在乎。但是Applicative Functor表示计算,并且f a = ()在组合之前将众所周知的计算进行组合,因此无论以后是否使用其计算值,每个函数都将得到[[performed。

© www.soinside.com 2019 - 2024. All rights reserved.