![](/img/trans.png)
[英]How do I create a functor instance for a type with two arguments, where both arguments have to be the same type?
[英]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
来返回Maybe (a, String)
,如果result
存在,这会将f
应用于result
。 如果我们构建了一个Parser
来返回[(a, String)]
,这会将f
应用于列表中返回的每个result
。
我们可以实例化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 Functor m => Functor (Parser m) where
fmap f (Parser p) = Parser (\x -> fmap g (p x))
where g (r, s) = (f r, s)
因此,这里g
是一个 function ,它在元组的第一个元素上执行映射f
。 因此,我们使用该g
作为结果的“映射” function。
因此,这将适用于作为Functor
实例的任何m
,例如Maybe
、 []
、 Tree
等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.