简体   繁体   English

GHC为什么不解析“数据包装fa =包装(fa)”的函子实例?

[英]Why does GHC not parse functor instance for 'data Wrap f a = Wrap (f a)'?

In Haskell Programming From First Principles section 16.13, the Wrap datatype is presented to demonstrate a type whose Functor instance requires a typeclass constraint on one of its parameters: Haskell从第一原理编程中的 16.13节中,展示了Wrap数据类型,以演示其Functor实例对其参数之一要求类型限制的类型:

data Wrap f a =
  Wrap (f a)
  deriving (Eq, Show)

After demonstrating a couple of incorrect instances of Functor for (Wrap f), a correct instance is shown: 在为(包装f)演示了几个错误的Functor实例后,显示了正确的实例:

instance Functor f => Functor (Wrap f) where
  fmap g (Wrap fa) = Wrap (fmap g fa)

The fact that this typeclass instance should work seems right to me. 这个类型类实例应该工作的事实在我看来是正确的。 Indeed, GHC accepts it without complaint. 实际上,GHC毫无保留地接受了它。

In order to convince myself that the 'Functor f' constraint is required, I attempted to create my own typeclass instance without it. 为了使自己确信需要'Functor f'约束,我尝试在没有该约束的情况下创建自己的typeclass实例。 My approach focuses on pattern matching to use f in a "functor-ish" way without fmap, similar to approaches shown earlier in the book. 我的方法着重于模式匹配,以在没有fmap的情况下以“ functor-ish”方式使用f,类似于本书前面所展示的方法。 Here is the attempt: 这是尝试:

instance Functor (Wrap f) where
  fmap g (Wrap (f a)) = Wrap f (g a)

When I load this into GHCi, I get the following error: 将其加载到GHCi中时,出现以下错误:

Prelude> :l 16.12-wrap.hs
[1 of 1] Compiling Main             ( 16.12-wrap.hs, interpreted )

16.12-wrap.hs:10:17: error: Parse error in pattern: f
   |
10 |   fmap g (Wrap (f a)) = Wrap f (g a)
   |                 ^^^
Failed, no modules loaded.

Can someone explain the issue with my attempted instance? 有人可以用我尝试的实例解释问题吗? It seems to me that GHC has enough information to infer that f is of kind (* -> *) from the definition of Wrap at the top, so I can't understand why my attempt does not parse. 在我看来,GHC具有足够的信息,可以从顶部的Wrap定义中推断出f是(*-> *)类型,因此我无法理解为什么我的尝试无法解析。

fmap g (Wrap (fa)) on the left hand side of the definition results in a parse error because (fa) is not a syntactically valid pattern. 定义左侧的fmap g (Wrap (fa))导致分析错误,因为(fa)不是语法上有效的模式。

My approach focuses on pattern matching to use f in a "functor-ish" way without fmap [...] 我的方法专注于模式匹配,以“ functor-ish”方式使用f,而没有fmap [...]

Syntax issue aside, you can't literally use that f as a pattern in this way. 除了语法问题,您不能以这种方式从字面上使用f作为模式。 The f in the instance declaration is a type constructor, while patterns are meant to match values and values constructors. 实例声明中的f是类型构造函数,而模式旨在匹配值和值构造函数。 For a minimal illustration, in... 对于最小的说明,在...

id :: x -> x
id x = x

... the x from the type signature, a type variable, is not the same x from the left side of the function definition, a pattern which matches values (of type x ) and binds them to a variable (named x ). ...来自类型签名的x (类型变量)与函数定义左侧的x不同,后者是匹配值(类型x )并将其绑定到变量(名为x )的模式。 There is no reason why the names must coincide. 名称没有理由必须重合。

If I understood your intent well, the plan was to use (fa) as a pattern such that f would match any "functor-ish" constructor with something (the a ) inside. 如果我能很好地理解您的意图,则计划将(fa)用作一种模式,以使f与内部带有( a )的任何“ functor-ish”构造函数匹配。 That doesn't work (we can't abstract over constructors in this manner), but even if it did somehow work it wouldn't be good enough for this task. 那是行不通的(我们不能以这种方式对构造函数进行抽象),但是即使它以某种方式起作用了,也不能胜任这项任务。 That's because not all functorial values fit the mould of a constructor wrapping some other value. 这是因为并非所有函数值都适合包装其他值的构造函数。 One example: Nothing :: Maybe Integer . 一个例子: Nothing :: Maybe Integer There is no unary value constructor here, nor any value being wrapped. 这里没有一元值构造函数,也没有包装任何值。

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

相关问题 为什么不能将(Functor f)=&gt; ConcreteType-&gt; f String制成实例Functor((-&gt;)ConcreteType)? - Why can I not make a (Functor f) => ConcreteType -> f String into an instance Functor ((->) ConcreteType)? 为什么`让foo =(fmap.const)`失败“因为使用`fmap&#39;而没有(Functor f0)的实例? - Why does `let foo = (fmap . const)` fail with “No instance for (Functor f0) arising from a use of `fmap'”? (newtype Mu f = InF {outF :: f (Mu f)}) 的函子实例 - Functor instance for (newtype Mu f = InF {outF :: f (Mu f)}) &#39;f&#39;在仿函数的fmap函数中表示什么? - What does the 'f' represent in the fmap function of a functor? (&lt;*&gt;):: f(a-&gt; b)-&gt; fa-&gt; fb在Functor类中到底做了什么 - what does (<*>) :: f (a -> b) -> f a -> f b exactly do in the Functor class 以下类型的 Functor 实例是什么: newtype F2 xa = F2 ((a -&gt; x) -&gt; a) - What would be the Functor instance for the following type: newtype F2 x a = F2 ((a -> x) -> a) F#中的Haskell应用函子 - Haskell Applicative Functor in F# Haskell:是否有这样的运算符:(&lt;$$&gt;):: Functor f =&gt; fa-&gt;(a-&gt; b)-&gt; fb - Haskell: Is there an operator like this: (<$$>) :: Functor f => f a -> (a -> b) -> f b p &gt;&gt; = f在解析器实例中如何工作? - How does p >>= f works in Parser instance? 为什么这个Functor实例不正确? - Why is this Functor instance incorrect?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM