如何为具有两个参数的类型实例化“Functor”?
How can I instance `Functor` for a type with two parameters?
背景。 在我的一个 类 中,我们一直在探索 Parser
monad。 Parser
monad 通常定义为
newtype Parser a = Parser (String -> [(a, String)])
或
newtype Parser a = Parser (String -> Maybe (a, String))
无论哪种情况,我们都可以使用适用于这两种情况的代码将 Parser
实例化为 Functor
:
instance Functor Parser where
fmap f (Parser p) = Parser (fmap applyF . p)
where applyF (result, s) = (f result, s)
如果我们有 Parser
构建到 return Maybe (a, String)
,如果 result
存在,这会将 f
应用于 result
。如果我们有一个 Parser
构建到 return [(a, String)]
,这将 f
应用于列表中 result
的每个 return。
我们可以实例化 Applicative
、Monad
、MonadPlus
和 Alternative
是类似的通用方式(因此它们适用于 Maybe
或 []
).
问题。如果我根据用于包装结果的类型参数化Parser
,我如何为Functor
和朋友实例化它?
newtype Parser m a = Parser (String -> m (a, String))
-- How do I instance `Parser` as a Functor if `m` is a Functor?
您可以在此处构造一个约束条件,即 m
也应该是 Functor
的一个实例类型,然后 fmap
该结果:
instance <b>Functor m</b> => Functor (Parser m) where
fmap f (Parser p) = Parser (\x -> <b>fmap g</b> (p x))
where <b>g</b> (r, s) = (f r, s)
因此,g
是一个对元组的第一个元素执行映射 f
的函数。因此,我们将 g
用作结果的 "mapping" 函数。
因此,这将适用于作为 Functor
实例的任何 m
,例如 Maybe
、[]
、Tree
等.
背景。 在我的一个 类 中,我们一直在探索 Parser
monad。 Parser
monad 通常定义为
newtype Parser a = Parser (String -> [(a, String)])
或
newtype Parser a = Parser (String -> Maybe (a, String))
无论哪种情况,我们都可以使用适用于这两种情况的代码将 Parser
实例化为 Functor
:
instance Functor Parser where
fmap f (Parser p) = Parser (fmap applyF . p)
where applyF (result, s) = (f result, s)
如果我们有 Parser
构建到 return Maybe (a, String)
,如果 result
存在,这会将 f
应用于 result
。如果我们有一个 Parser
构建到 return [(a, String)]
,这将 f
应用于列表中 result
的每个 return。
我们可以实例化 Applicative
、Monad
、MonadPlus
和 Alternative
是类似的通用方式(因此它们适用于 Maybe
或 []
).
问题。如果我根据用于包装结果的类型参数化Parser
,我如何为Functor
和朋友实例化它?
newtype Parser m a = Parser (String -> m (a, String))
-- How do I instance `Parser` as a Functor if `m` is a Functor?
您可以在此处构造一个约束条件,即 m
也应该是 Functor
的一个实例类型,然后 fmap
该结果:
instance <b>Functor m</b> => Functor (Parser m) where
fmap f (Parser p) = Parser (\x -> <b>fmap g</b> (p x))
where <b>g</b> (r, s) = (f r, s)
因此,g
是一个对元组的第一个元素执行映射 f
的函数。因此,我们将 g
用作结果的 "mapping" 函数。
因此,这将适用于作为 Functor
实例的任何 m
,例如 Maybe
、[]
、Tree
等.