Functor的实例

时间:2017-04-03 07:04:49

标签: haskell 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

所以,请帮帮我

2 个答案:

答案 0 :(得分:4)

Functor类的定义如下:

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

因此,fmap的{​​{1}}定义为:

Arr2

或更优雅:

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

或更优雅的版本 - 由@Alec评论:

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

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

答案 1 :(得分:0)

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
相关问题