首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于ADTs的fmap推断

关于ADTs的fmap推断
EN

Stack Overflow用户
提问于 2015-09-20 14:59:51
回答 1查看 98关注 0票数 1

假设两个新类型的定义如下所示

代码语言:javascript
复制
type MyProductType a = (FType1 a, FType2 a)

type MyCoproductType a = Either (FType1 a) (FType2 a)

...and,FType1Ftype2都是Functor的实例。

如果现在将MyProductTypeMyCoproductType声明为Functor的实例,编译器是否需要对它们各自的fmap进行显式定义,还是可以从前面的定义中推断出这些定义?

另外,这个问题的答案是依赖于实现的,还是来自Haskell规范?

作为背景,这个问题的动机是试图理解我正在读的东西中的一句话。作者首先定义了

代码语言:javascript
复制
type Writer a = (a, String)

...and后来写到(我的重点)

...the Writer类型构造函数是a中的函数。我们甚至不需要为它实现fmap,因为它只是一个简单的产品类型。

强调的文本是我想要理解的注释。我认为这意味着Haskell可以根据函数式类型推断出任何ADT的fmap,特别是,它可以推断出像Writer这样的“简单产品类型”的fmap,但现在我认为这种解释是不正确的(至少如果我正确地阅读了厄詹·约翰森的答案)。

至于作者所说的那句话是什么意思,我现在真的一无所知。也许他的意思是,用这样一种方式重新定义Writer是不值得的,因为它是一种“简单的.类型”。(在这里抓吸管)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-20 15:13:59

首先,您通常不能为type同义词定义新实例,特别是不能像在您的情况下所需要的那样部分应用实例。我认为您的意思是定义newtypedata,而不是:

代码语言:javascript
复制
newtype MyProductType a = MP (FType1 a, FType2 a)
newtype MyCoproductType a = MC (Either (FType1 a) (FType2 a))

标准Haskell完全没有提到自动派生Functor,这只有在GHC的DeriveFunctor扩展中才有可能。(有时是GeneralizedNewtypeDeriving,但这在示例中不适用,因为您没有使用a作为构造函数中的最后一个参数。)

所以让我们试试:

代码语言:javascript
复制
{-# LANGUAGE DeriveFunctor #-}
data FType1 a = FType1 a deriving Functor
data FType2 a = FType2 a deriving Functor
newtype MyProductType a = MP (FType1 a, FType2 a) deriving Functor
newtype MyCoproductType a = MC (Either (FType1 a) (FType2 a)) deriving Functor

我们得到错误消息:

代码语言:javascript
复制
Test.hs:6:76:
    Can't make a derived instance of ‘Functor MyCoproductType’:
      Constructor ‘MC’ must use the type variable only as the last argument of a data type
    In the newtype declaration for ‘MyCoproductType’

结果表明,GHC可以导出前三个,但不能导出最后一个。我认为第三种只有因为元组是特殊的大小写才起作用的。但是,Either不起作用,因为GHC没有对Either如何对待其第一个参数保持任何特殊的知识。在这个论点中,它名义上是一个数学函子,但不是Haskell Functor

请注意,GHC只将变量用作已知为Functors的类型的最后一个参数是更明智的。

代码语言:javascript
复制
newtype MyWrappedType a = MW (Either (FType1 Int) (FType2 (Maybe a))) deriving Functor

总之:它取决于,GHC对此有一个扩展,但是它并不总是足够聪明来做你想做的事情。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32680771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档