如何为具有两个参数的类型实例化“ Functor”?

J. *_*rez 4 haskell functional-programming functor typeclass parameterized-types

背景。在我的一堂课中,我们一直在探索Parser单子。Parser通常将monad定义为

newtype Parser a = Parser (String -> [(a, String)])
Run Code Online (Sandbox Code Playgroud)

或作为

newtype Parser a = Parser (String -> Maybe (a, String))
Run Code Online (Sandbox Code Playgroud)

无论哪种情况,我们都可以Parser作为在两种情况下都可以Functor使用的使用代码实例化:

instance Functor Parser where
  fmap f (Parser p) = Parser (fmap applyF . p)
    where applyF (result, s) = (f result, s)
Run Code Online (Sandbox Code Playgroud)

如果我们有一个Parser建回报Maybe (a, String),这适用fresult如果result存在。如果我们有一个Parserreturn 的构建体[(a, String)],则这适用于列表中返回的f每个result

我们可以例如ApplicativeMonadMonadPlus,和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?
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 9

您可以在此处构造一个约束,该约束也m应该是作为Instance的类型的类型,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)
Run Code Online (Sandbox Code Playgroud)

g因此,这是一个f在元组的第一个元素上执行映射的函数。因此,我们将其g用作结果的“映射”功能。

因此,这将适用于任何m实例Functor,例如a Maybe,a [],a Tree等。