包含函数的数据类型的函子实例

Functor instance for datatype containing function

我的数据类型定义为

data Foo a = Foo a (a -> a)

Foo数据构造函数有两个参数值和函数。我需要为此编写 Monad 和 Monad 转换实例。

我正在尝试实现仿函数实例,

instance Functor Foo where 
  fmap f (Foo x g) = Foo (f x) (g .(f x))

但是我得到一个错误 Couldn't match type ‘a’ with ‘b’

这是正确的,因为 g 只接受类型 af x 将转换 a->b 。所以接下来我重写为

instance Functor Foo where 
  fmap f (Foo x g) = Foo (f x) g

我遇到了同样的错误“无法将类型‘a’与‘b’匹配”。

我也试过这个

instance Functor Foo where 
  fmap f (Foo x g) = Foo (f x) (f. g x)

Occurs check: cannot construct the infinite type: a ~ b -> a (g.x)

我卡住了,我知道函数 g 只接受类型 a 和 returns 类型 a。但是 fmap 会将类型 a 转换为类型 b。我想我也必须在 g 上应用 fmap,但我做不到。

如何为上述数据类型编写实例?

让我们考虑类型,我们基本上需要将 Foo a 转换为 Foo b,这意味着我们需要在给定函数 a -> b 的情况下找到一个元素a 类型的函数和 a -> a 类型的函数、b 类型的元素和 b -> b.

类型的函数

尤其是最后一个比较难,因为我们只给了一个a -> b类型的函数,而不是b -> a类型的函数,我们不能先把输入转换成[=14] =],然后通过原始函数处理,然后映射回一个b.

做一个满足类型的映射也不是完全不可能,例如:

fmap<sub>1</sub> f (Foo x g) = Foo (f x) (<b>const (f x)</b>)

或:

fmap<sub>2</sub> f (Foo x g) = Foo (f x) <b>id</b>

但是 fmap<sub>1</sub>fmap<sub>2</sub>[ 的问题=54=]需要满足定律:</p> <pre><code>fmap id = id

换句话说fmap id (Foo x g)需要等于Foo x g,现在如果我们使用idconst (f x),那么idf x 并不总是等于 g,至少如果 g 是一个可以采用任何形式的函数。

如果您当然认为 Foo x gFoo x (id x) 是等价的,在某些情况下 可能是合理的,那么您可以将其实现为仿函数实例.