我在理解这段代码时缺少了什么关键的直觉?我不明白它们是如何组成的。第一个期望一个函数(a-〉c)和构造的类型(f a b)。然而,第二个产生(f a d)。此外,第一个和第二个是用双Map定义的,这似乎是循环的。
class Bifunctor f where
bimap :: (a -> c) -> (b -> d) -> f a b -> f c d
bimap g h = first g . second h
first :: (a -> c) -> f a b -> f c b
first g = bimap g id
second :: (b -> d) -> f a b -> f a d
second = bimap id
1条答案
按热度按时间6jygbczu1#
second
是 curried 。 您 可以 写入 隐含 的 参数 , 它 将 与first
对称 。中 的 每 一 个
至于 你 的 问题 , 这些 定义 是否 是 循环 的 , 答案 是 肯定 的 。 它们 是 循环 的 。
格式
根据 Haskell 标准 , 它 可以 编译 , 但是 任何 调用
first
、second
或bimap
的 尝试 都 将 失败 , 因为 它们 将 永远 相互 调用 。但是 , 如果 您 查看
Bifunctor
的 源 代码 , 就会 发现 还有 一 个 小 注解 。格式
这 不是 一 个 普通 的 评论 。 这 是 一 个 针对 GHC 的 特别 指示( 最 流行 的 Haskell 编译 器 ) 。 GHC 特别 支持 最 小 指令 。 这 声明 了
Bifunctor
的 示例 只有 在 实现 了 * 至少 *bimap
或 同时 实现 了first
和second
时 才 是 完整 的 。 因此 , 在 GHC 上 , 如果 您 在 自己 的instance
中 未能 满足 该 条件 ,你 会 得到 一 个 编译 器 错误 。 这 也 反映 在 Hackage 文档格式
作为 程序 员 , 我们 希望 您 覆盖 其中 的 一些 默认 值 , 而 其余 的 默认 值 可以 默默 地 就位 。
您 可以 在 内置 类型 类
Eq
中 更 直接 地 看到 相同 的 行为格式
(==)
和(/=)
都 是 根据 对方 来 实现 的 , 底部 有 一 个MINIMAL
指令 , 指示 任何 示例 都 必须 至少 实现 这 两 个 函数 中 的 一 个 。