如何解决将参数化类型 List 更改为 Functor 类的实例
我是 Functor 的新手,所以我已经参数化了类型 List,如下所示:
数据列表 a = 空 |一个|追加(列表a)(列表a)
并且问题要求我将其更改为 Haskell 语法中 Functor 类的一个实例。我正在努力为每个 fmap 定义
解决方法
这里又是你的结构(格式更好一些):
data List a
= Empty
| One a
| Append (List a) (List a)
您需要为此定义一个 Functor-Instance,所以让我们从 3 个构造函数的模式匹配开始:
instance Functor List where
fmap f Empty = ...
fmap f (One a) = ...
fmap f (Append a b) = ...
在 Empty
中(除了像 undefined
这样的底值,...)实际上只有一种可能性 - 你必须返回一个 List a
- Empty
是可能的,对于 One
,您需要一个 a
值(您没有),而对于 Append
,您又需要两个 List
。当然,您可以采用 Append Empty Empty
,但请记住所有 Lists l 的 functor-laws 状态之一 fmap id l === l
(意思完全相同 - 不是 Haskell Eq
!) -所以只有一种选择:
instance Functor List where
fmap _ Empty = Empty
对于 One
它是类似的:你需要 fmap id (One a) === One a
所以构造函数是固定的,对于一般情况 fmap :: (a -> b) -> List a -> List b
你看到你必须在包装的 f
上使用a
中的 {1}}-值:
One
最后是 instance Functor List where
fmap f (One a) = One (f a)
的情况。现在你应该知道这需要再次产生 Append
(functor-law) 并且右侧 Append (..) (..)
的两个参数需要是 Append
。现在当你有 List b
时如何得到 List b
?如果你环顾四周:List a
所以你有办法把 fmap f :: List a -> List b
s(你有两个在范围内)变成 List a
s(也许并不奇怪,因为 List b
是也是递归的),而且函子律只让你一个选择(为什么?):
Append
所以你得到:
instance Functor List where
fmap f (Append a a') = Append (fmap f a) (fmap f a')
PS:通常 - 不是家庭作业 - 你可以这样做:
instance Functor List where
fmap _ Empty = Empty
fmap f (One a) = One (f a)
fmap f (Append a b) = Append (fmap f a) (fmap f b)
GHC 会为您解决这个问题;)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。