自动函子实例 [英] Automatic Functor Instance

查看:109
本文介绍了自动函子实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下代数类型:

  ghci> data Foo a = Foo a 

然后我实例化其中的一个。

  ghci>让f = Foofoo

最后,我想调用 fmap 将函数应用为,(a - > b) - > Foo a - > Foo b

  ghci> fmap(++bar)f 

< interactive>:78:1:
由于使用'fmap'而没有实例(Functor Foo)
In表达式:fmap(++bar)f
在等式'it'中:it = fmap(++bar)f

但是,因为我没有实现 Functor Foo ,我不能使用 fmap



有没有办法获得 Functor 实例是免费的吗?我对Haskell的编译器知之甚少,但也许知道 Foo a 上的 fmap 仅仅适用于(a - > b) Foo a

解决方案

在ghci中工作,如果你做了咒语

 前奏> :set -XDeriveFunctor 

然后编译器会变得像你所期望的那样聪明,热情。您将需要调用该功能,因此,

  Prelude>数据Foo a = Foo a派生(Show,Functor)

Show 仅用于打印输出,如下所示),然后您就可以执行诸如

 前奏> fmap(++bar)(Foofoo)
Foofoobar

在一个模块中,通过添加附注来达到同样的效果

  { - #LANGUAGE DeriveFunctor# - } 

模块声明之前。这对于至少更简单的 Functor 实例是很好的,但是你可以将它伪装成一个错误的否定。

 前奏>数据Boo a = Boo(或者Bool)派生Functor 

< interactive>:9:43:
无法创建'Functor Boo'派生实例:
构造函数'Boo'必须仅使用类型变量作为数据类型的
最后一个参数
在'Boo'的数据声明中


 数据Goo a = Goo(或者Bool a)派生Functor 

没问题,并且机器显然已被黑客入侵,因为

  data Woo a = Woo(a,Bool)派生Functor 

是允许的。



所以它不像它那么聪明,但是它比眼中的捅。 p>

Given the following algebraic type:

ghci> data Foo a = Foo a

Then I instantiate one of them.

ghci> let f = Foo "foo"

Lastly, I'd like to call fmap to apply a function as, (a -> b) -> Foo a -> Foo b.

ghci> fmap (++ "bar") f

<interactive>:78:1:
    No instance for (Functor Foo) arising from a use of ‘fmap’
    In the expression: fmap (++ "bar") f
    In an equation for ‘it’: it = fmap (++ "bar") f

But, since I didn't implement a Functor instance of Foo, I can't use fmap.

Is there a way to get Functor instances for free? I have zero knowledge of Haskell's compiler, but perhaps it's clever enough to know that fmap on Foo a is simply apply (a -> b) to Foo's a?

解决方案

Working in ghci, if you make the incantation

Prelude> :set -XDeriveFunctor

then the compiler will become as clever as you are hoping for, if not quite as enthusiastic. You will need to invoke the functionality, thus,

Prelude> data Foo a = Foo a deriving (Show, Functor)

(the Show is just for printing the output, below) and then you will be able to do stuff like

Prelude> fmap (++"bar") (Foo "foo")
Foo "foobar"

In a module, you achieve the same by adding the pragma

{-# LANGUAGE DeriveFunctor #-}

before the module declaration. It's good for at least the more straightforward Functor instances, but you can fool it into a false negative.

Prelude> data Boo a = Boo (Either a Bool) deriving Functor

<interactive>:9:43:
    Can't make a derived instance of ‘Functor Boo’:
      Constructor ‘Boo’ must use the type variable only as the
        last argument of a data type
      In the data declaration for ‘Boo’

Meanwhile

data Goo a = Goo (Either Bool a) deriving Functor

is ok, and the machinery has clearly been hacked to work with pairing, as

data Woo a = Woo (a, Bool) deriving Functor

is permitted.

So it's not as clever as it could be, but it's better than a poke in the eye.

这篇关于自动函子实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆