繁体   English   中英

如何为具有两个参数的类型实例化 `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来返回Maybe (a, String) ,如果result存在,这会将f应用于result 如果我们构建了一个Parser来返回[(a, String)] ,这会将f应用于列表中返回的每个result

我们可以实例化ApplicativeMonadMonadPlusAlternative是类似的通用方式(因此它们适用于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM