函子的实例

Instance of a Functor

我有以下类型newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a }。 我必须为它编写 Functor 实例,但我真的不明白如何 我试过了

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (g a)

instance Functor (Arr2 e1 e2) where
  fmap g = g . getArr2

这实际上导致类型

(a -> b) -> Arr2 e1 e2 a -> b

而不是期望的

(a -> b) -> Arr2 e1 e2 a -> Arr2 e1 e2 b

所以,请帮助我

Functor class 定义为:

class Functor f where:
    fmap :: (a -> b) -> f a -> f b
    (<$) :: a -> f b -> f a

(<$) 有一个默认实现:(<$) = fmap . const 工作正常。

所以这意味着如果我们输入一个函数 (g :: a -> b) 作为第一个参数,并且一个 Arr2 产生一个 a,我们必须产生一个 Arr2 如果应用它,则在箭头的 结果 上调用 g

因此,您的 Arr2fmap 的定义是:

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (<b>\x y -> g (a x y)</b>)

或者更优雅:

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (<b>\x -> g . (a x)</b>)

或更优雅的版本 - 评论:

instance Functor (Arr2 e1 e2) where
  fmap g (Arr2 a) = Arr2 (<b>(g .) . a</b>)

(您可以使用 this tool 将表达式转换为 pointfree

Willem Van Onsem 提供的答案非常好,我只想建议使用可以轻松为新类型创建 Functor 实例的语言扩展:DeriveFunctor

在模块的顶部,您可以添加:

{-# LANGUAGE DeriveFunctor #-}

然后你可以自动派生出你的Functor实例:

newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor

以下是我如何在 GHCi 中找出此实例的 fmap 类型:

λ > :set -XDeriveFunctor
λ > newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor
λ > :set -XTypeApplications 
λ > :t fmap @(Arr2 _ _)
fmap @(Arr2 _ _) :: (a -> b) -> Arr2 t t1 a -> Arr2 t t1 b