简体   繁体   English

模式中的解析错误:f。 g在fmap中(f.g)= fmap f。 fmap g

[英]Parse error in pattern: f . g in fmap (f . g) = fmap f . fmap g

Parse error in pattern: f . 模式中的解析错误:f。 g G

i am a beginner, where is wrong? 我是初学者,哪里错了?

   (f . g) x = f (g x)


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

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

instance Functor F where
    fmap id = id 
    fmap (f . g)  = fmap f . fmap g

When you make an instance of Functor, you should prove the side condition that 当你创建一个Functor的实例时,你应该证明它的边缘条件

fmap id = id 

and

fmap (f . g)  = fmap f . fmap g

(Technically the latter comes for free given the types involved and the former law, but it is still a good exercise.) (从技术上讲,后者是免费的,因为涉及的类型和前法律,但它仍然是一个很好的练习。)

You can't do this just by saying 你不能这样说

fmap id = id

but instead you use this as a reasoning tool -- once you have proven it. 但相反,你使用它作为推理工具 - 一旦你证明了它。

That said, the code that you have written doesn't make sense for a number of reasons. 也就是说,由于多种原因,您编写的代码没有意义。

  (f . g) x = f (g x)

Since this is indented, I'm somewhat unclear if this is intended to be a definition for (.), but that is already included in the Prelude, so you need not define it again. 由于这是缩进的,我有点不清楚这是否是(。)的定义,但是已经包含在Prelude中,所以你不需要再次定义它。

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

This definition is also provided for you in the Prelude. Prelude中也为您提供了此定义。

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

But then you define the class again, but here it has mangled the signature of fmap, which would have to be 但是你再次定义了这个类,但是在这里它已经破坏了fmap的签名,这必须是

    fmap :: (a -> b) -> g a -> g b

But as you have another definition of Functor right above (and the Prelude has still another, you couldn't get that to compile) 但是正如你在上面有另一个Functor的定义(并且Prelude还有另一个,你无法编译)

Finally, your 最后,你的

instance Functor F where
    fmap id = id 
    fmap (f . g)  = fmap f . fmap g

makes up a name F for a type that you want to make into an instance of Functor , and then tries to give the laws as an implementation, which isn't how it works. 为你想要成为Functor实例的类型组成一个名称F ,然后尝试将法律作为一个实现,这不是它的工作原理。

Let us take an example of how it should work. 让我们举一个它应该如何工作的例子。

Consider a very simple functor: 考虑一个非常简单的仿函数:

data Pair a = Pair a a

instance Functor Pair where
   fmap f (Pair a b) = Pair (f a) (f b)

now, to prove fmap id = id , let us consider what fmap id and id do pointwise: 现在,为了证明fmap id = id ,让我们考虑一下fmap idid做什么的:

fmap id (Pair a b) = -- by definition
Pair (id a) (id b) = -- by beta reduction
Pair a (id b) = -- by beta reduction
Pair a b

id (Pair a b) = -- by definition
Pair a b

So, fmap id = id in this particular case. 所以,在这种特殊情况下, fmap id = id

Then you can check (though technically given the above, you don't have to) that fmap f . fmap g = fmap (f . g) 然后你可以检查(虽然技术上给出了上述,你没有) fmap f . fmap g = fmap (f . g) fmap f . fmap g = fmap (f . g)

(fmap f . fmap g) (Pair a b) = -- definition of (.)
fmap f (fmap g (Pair a b)) = -- definition of fmap 
fmap f (Pair (g a) (g b)) = -- definition of fmap
Pair (f (g a)) (f (g b))

fmap (f . g) (Pair a b) = -- definition of fmap
Pair ((f . g) a) ((f . g) b) = -- definition of (.)
Pair (f (g a)) ((f . g) b) = -- definition of (.)
Pair (f (g a)) (f (g b))

so fmap f . fmap g = fmap (f . g) 所以fmap f . fmap g = fmap (f . g) fmap f . fmap g = fmap (f . g)

Now, you can make function composition into a functor. 现在,您可以将函数组合转换为仿函数。

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

by partially applying the function arrow constructor. 通过部分应用函数箭头构造函数。

Note that a -> b and (->) ab mean the same thing, so when we say 注意a -> b(->) ab意思相同,所以当我们说

instance Functor ((->) e) where

the signature of fmap specializes to fmap的签名专门用于

    fmap {- for (->) e -} :: (a -> b) -> (->) e a -> (->) e b

which once you have flipped the arrows around looks like 一旦你翻转箭头看起来像

    fmap {- for (->) e -} :: (a -> b) -> (e -> a) -> e -> b

but this is just the signature for function composition! 但这只是功能构成的签名!

So 所以

instance Functor ((->)e) where
    fmap f g x = f (g x)

is a perfectly reasonable definition, or even 是一个非常合理的定义,甚至是

instance Functor ((->)e) where
    fmap = (.)

and it actually shows up in Control.Monad.Instances . 它实际上出现在Control.Monad.Instances中

So all you need to use it is 所以你只需要使用它

import Control.Monad.Instances

and you don't need to write any code to support this at all and you can use fmap as function composition as a special case, so for instance 并且你根本不需要编写任何代码来支持它,你可以使用fmap作为特殊情况的函数组合,例如

fmap (+1) (*2) 3 = 
((+1) . (*2)) 3 =
((+1) ((*2) 3)) =
((+1) (3 * 2)) = 
3 * 2 + 1 =
7

Since . 自从. is not a data constructor you cannot use it for pattern matching I believe. 不是数据构造函数,你不能用它来进行模式匹配我相信。 As far as I can tell there isn't an easy way to do what you're trying, although I'm pretty new to Haskell as well. 据我所知,没有一种简单的方法可以做你正在尝试的事情,尽管我对Haskell也很新。

let is not used for top-level bindings, just do: let不用于顶级绑定,只需:

f . g = \x -> f (g x)

But the complaint, as cobbal said, is about fmap (f . g) , which isn't valid. 但是,正如cobbal所说,投诉是关于fmap (f . g) ,这是无效的。 Actually, that whole class Functor F where is screwy. 实际上, class Functor F where搞砸了。 The class is already declared, now I think you want to make and instance : 该类已经声明,现在我认为你想制作和instance

instance Functor F where
    fmap SomeConstructorForF = ...
    fmap OtherConstructorForF = ...

etc. 等等

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

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