简体   繁体   English

Functor的实例

[英]Instance of a Functor

I have a following type newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } . 我有以下类型newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } And I got to write Functor instance for it, yet i don't really understand how I tried 我必须为它编写Functor实例,但我真的不明白我的尝试方式

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

and

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

which actually results in type 这实际上导致了类型

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

instead of desired 而不是期望

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

So please, help me 所以,请帮助我

The Functor class has as definition: Functor类具有以下定义:

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

The (<$) has a default implementation: (<$) = fmap . const (<$)有一个默认实现: (<$) = fmap . const (<$) = fmap . const which works fine. (<$) = fmap . const工作得很好。

So that means that if we enter a function ( g :: a -> b ) as first argument, and an Arr2 that produces an a , we have to generate an Arr2 that calls that g on the outcome of the arrow if it is applied. 这意味着如果我们输入一个函数( g :: a -> b )作为第一个参数,并且一个Arr2产生一个a ,我们必须生成一个Arr2 ,如果它被应用,则在箭头的结果上调用g

As a result the definition of fmap for your Arr2 is: 因此,您的Arr2fmap定义是:

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

Or more elegantly: 或者更优雅:

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

Or a more elegant version - commented by @Alec : 或更优雅的版本 - 由@Alec评论:

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

(you can convert expressions to pointfree ones using this tool ) (你可以转换使用表达式来pointfree那些该工具

The answer provided by Willem Van Onsem is very good, I would just like to suggest the use of a language extension that can easily create Functor instances for newtypes: DeriveFunctor . Willem Van Onsem提供的答案非常好,我只想建议使用一种语言扩展,可以轻松地为newtypes创建Functor实例: DeriveFunctor

At the top of your module you can add: 在模块的顶部,您可以添加:

{-# LANGUAGE DeriveFunctor #-}

Then you can automatically derive your Functor instance: 然后,您可以自动派生您的Functor实例:

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

Here's is how I would find out the type of fmap for this instance in GHCi: 以下是我如何在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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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