Alternative
、Applicative
の拡張、empty
、<|>
、およびこれら2つの関数を宣言します。
1つ以上:
some :: f a -> f [a]
ゼロ以上:
many :: f a -> f [a]
定義されている場合、
some
とmany
は方程式の最小解である必要があります。some v = (:) <$> v <*> many v many v = some v <|> pure []
some
とmany
が定義されているインスタンスが見つかりませんでした。 それらの意味と実用性は何ですか?それらはまったく使用されていますか?この定義だけでは、その目的を理解することができませんでした。
更新:私はAlternative
とは何かを尋ねているのではなく、some
とmany
とは何かを尋ねています。
私はそれらをApplicative
パーサーコンビネーターライブラリで見る傾向があります。
a :: Parser [String]
a = some (string "hello")
そして、many
がParsing
の- デフォルトのparsers
の定義で使用されているのがわかります。
パーサーコンビネーターライブラリの主要な例であるParsecは、(<|>)
のようなものを再定義するため、some
/many
の使用を隠していると思います。
基本的な例のインスタンス:with
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 _ = []
我々は持っています
*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-> [])
我々が得る
*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 ^^^^^^^^^^^^^^^^^^^ -}
STM Applicativeでは、some
は次のことを意味します。少なくとも1回成功するまで試行を続け、その後失敗するまで試行を続けます。 many
は、次のことを意味します。失敗するまで、これをできるだけ多く実行します。
これらのメソッドの使用を動機付ける良い例を提供しますが、型クラスについてはまだ誤解しているようです。
型クラス定義は、型クラスのすべてのインスタンスに存在するメソッドの型シグネチャを一覧表示します。また、これらのメソッドのデフォルトの実装を提供する場合もあります。これは、Alternativeのsomeおよびmanyメソッドで発生していることです。
有効なインスタンスであるためには、すべてのメソッドをインスタンスに対して定義する必要があります。したがって、具体的にsomeまたはmanyのインスタンスを定義しなかったものはdefaultの実装であり、それらのコードは質問にリストされているとおりです。
したがって、明確にするために、一部および多くは実際に定義されており、型クラス定義で指定されたデフォルト定義のおかげで、すべての代替インスタンスで使用できます。