gpt4 book ai didi

haskell - fmap (f . g) = fmap f . 中模式 : f . g 中的解析错误函数映射g

转载 作者:行者123 更新时间:2023-12-02 10:47:56 26 4
gpt4 key购买 nike

模式解析错误:f。克

我是初学者,哪里错了?

   (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

最佳答案

当您创建 Functor 实例时,您应该证明以下条件:

fmap id = id 

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

(从技术上讲,考虑到所涉及的类型和前一个法律,后者是免费的,但这仍然是一个很好的练习。)

你不能仅仅通过说来做到这一点

fmap id = id

但是,一旦你证明了这一点,你就可以将其用作推理工具。

也就是说,由于多种原因,您编写的代码没有意义。

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

由于这是缩进的,我有点不清楚这是否是 (.) 的定义,但它已经包含在 Prelude 中,因此您无需再次定义它。

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

序言中也为您提供了这个定义。

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

但是你再次定义了这个类,但这里它破坏了 fmap 的签名,这必须是

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

但是由于上面有 Functor 的另一个定义(并且 Prelude 还有另一个定义,因此您无法编译它)

最后,你的

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

为您想要使其成为Functor实例的类型命名一个名称F,然后尝试将法则作为实现,这不是'它是如何工作的。

让我们举一个例子来说明它应该如何工作。

考虑一个非常简单的仿函数:

data Pair a = Pair a a

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

现在,为了证明 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

因此,在这种特殊情况下,fmap id = id

然后您可以检查(尽管从技术上讲,您不必这样做)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)

现在,您可以将函数组合变成仿函数。

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

通过部分应用函数箭头构造函数。

请注意,a -> b(->) a b 表示相同的意思,所以当我们说

instance Functor ((->) e) where

fmap的签名专门用于

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

一旦你翻转箭头,就会看起来像

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

但这只是函数组合的签名!

所以

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

是一个完全合理的定义,甚至

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

它实际上出现在 Control.Monad.Instances 中.

所以你需要使用它的是

import Control.Monad.Instances

并且您根本不需要编写任何代码来支持这一点,并且您可以使用 fmap 作为函数组合作为特殊情况,例如

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

关于haskell - fmap (f . g) = fmap f . 中模式 : f . g 中的解析错误函数映射g,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5521870/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com