Pet*_*lák 35 haskell applicative
Alternative,的扩展Applicative,声明empty,<|>这两个功能:
一个或多个:
Run Code Online (Sandbox Code Playgroud)some :: f a -> f [a]零或更多:
Run Code Online (Sandbox Code Playgroud)many :: f a -> f [a]如果定义,
some并且many应该是方程的最小解:Run Code Online (Sandbox Code Playgroud)some v = (:) <$> v <*> many v many v = some v <|> pure []
我找不到一个实例some和many定义的实例.它们的含义和实际用途是什么?他们一直在使用吗?我只是从这个定义中无法理解他们的目的.
更新:我不是在问什么是什么Alternative,只是什么some和many
J. *_*son 13
我倾向于在Applicative解析器组合库中看到它们.
a :: Parser [String]
a = some (string "hello")
Run Code Online (Sandbox Code Playgroud)
我看到many用于该目的的默认定义Parsing中parsers.
我认为Parsec是解析器组合器库的主要示例隐藏了some/ 的使用,many因为它重新定义了类似的东西(<|>).
Wil*_*ess 12
一个基本的例子:用
import Control.Monad(Functor(..))
import Control.Applicative
import Data.Char
-- char string parser
newtype P a = P { runP :: String -> [(a,String)] }
-- runP (P p) s = p s
instance Functor P where
-- fmap :: (a -> b) -> f a -> f b
fmap f (P q) = P (\s -> [ (f y,ys) | (y,ys) <- q s])
instance Applicative P where
-- pure :: a -> f a
pure x = P (\s -> [(x,s)])
-- (<*>) :: f (a -> b) -> f a -> f b
P p <*> P q = P (\s -> [(x y, ys) | (x,xs) <- p s, (y,ys) <- q xs])
letter = P p where -- sample parser
p (x:xs) | isAlpha x = [(x,xs)]
p _ = []
Run Code Online (Sandbox Code Playgroud)
我们有
Run Code Online (Sandbox Code Playgroud)*Main Data.Char> runP letter "123" [] *Main Data.Char> runP letter "a123" [('a',"123")] *Main Data.Char> runP ( (:) <$> letter <*> pure []) "a123" [("a","123")] *Main Data.Char> runP ( (:) <$> letter <*> ((:)<$>letter <*> pure []) ) "a123" [] *Main Data.Char> runP ( (:) <$> letter <*> ((:)<$>letter <*> pure []) ) "ab123" [("ab","123")] -- NOT NICE ^^^^^^^^^^^^^^^^^^^^ -}
然后,用
instance Alternative P where
-- (<|>) :: f a -> f a -> f a
P p <|> P q = P (\s-> p s ++ q s)
-- empty :: f a -- the identity of <|>
empty = P (\s-> [])
Run Code Online (Sandbox Code Playgroud)
我们得到
Run Code Online (Sandbox Code Playgroud)*Main Data.Char> runP (many letter) "ab123" [("ab","123"),("a","b123"),("","ab123")] *Main Data.Char> runP (some letter) "ab123" [("ab","123"),("a","b123")] *Main Data.Char> runP (optional letter) "ab123" [(Just 'a',"b123"),(Nothing,"ab123")] *Main Data.Char> runP (optional letter) "123" [(Nothing,"123")] Prelude Main Data.Traversable> runP (sequenceA $ replicate 2 letter) "ab123" [("ab","123")] -- NICE ^^^^^^^^^^^^^^^^^^^ -}
Will 提供了一个很好的例子来激励使用这些方法,但您似乎仍然对类型类有误解。
类型类定义列出了该类型类的所有实例所存在的方法的类型签名。它还可能提供这些方法的默认实现,这就是 Alternative 的一些和许多方法所发生的情况。
为了成为有效的实例,必须为实例定义所有方法。因此,您发现没有专门为某些或许多对象定义实例的实例使用默认实现,并且它们的代码与您的问题中列出的完全相同。
因此,需要明确的是,由于类型类定义给出了默认定义,一些和许多确实已定义,并且可以与所有替代实例一起使用。
| 归档时间: |
|
| 查看次数: |
6988 次 |
| 最近记录: |