haskell 类型类的双Map如何没有循环定义

brccelvz  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(200)

我在理解这段代码时缺少了什么关键的直觉?我不明白它们是如何组成的。第一个期望一个函数(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
6jygbczu

6jygbczu1#

secondcurried 。 您 可以 写入 隐含 的 参数 , 它 将 与 first 对称 。

first g = bimap g id
second g = bimap id g

中 的 每 一 个
至于 你 的 问题 , 这些 定义 是否 是 循环 的 , 答案 是 肯定 的 。 它们 是 循环 的 。

data F a b = F a b

instance Bifunctor F -- No functions implemented; take all three defaults

格式
根据 Haskell 标准 , 它 可以 编译 , 但是 任何 调用 firstsecondbimap 的 尝试 都 将 失败 , 因为 它们 将 永远 相互 调用 。
但是 , 如果 您 查看 Bifunctor 的 源 代码 , 就会 发现 还有 一 个 小 注解 。

{-# MINIMAL bimap | first, second #-}

格式
这 不是 一 个 普通 的 评论 。 这 是 一 个 针对 GHC 的 特别 指示( 最 流行 的 Haskell 编译 器 ) 。 GHC 特别 支持 最 小 指令 。 这 声明 了 Bifunctor 的 示例 只有 在 实现 了 * 至少 * bimap 或 同时 实现 了 firstsecond 时 才 是 完整 的 。 因此 , 在 GHC 上 , 如果 您 在 自己 的 instance 中 未能 满足 该 条件 ,你 会 得到 一 个 编译 器 错误 。 这 也 反映 在 Hackage 文档

    • 最 小 完整 定义 * *
bimap | first, second

格式
作为 程序 员 , 我们 希望 您 覆盖 其中 的 一些 默认 值 , 而 其余 的 默认 值 可以 默默 地 就位 。
您 可以 在 内置 类型 类 Eq 中 更 直接 地 看到 相同 的 行为

class  Eq a  where
    (==), (/=)           :: a -> a -> Bool

    {-# INLINE (/=) #-}
    {-# INLINE (==) #-}
    x /= y               = not (x == y)
    x == y               = not (x /= y)
    {-# MINIMAL (==) | (/=) #-}

格式
(==)(/=) 都 是 根据 对方 来 实现 的 , 底部 有 一 个 MINIMAL 指令 , 指示 任何 示例 都 必须 至少 实现 这 两 个 函数 中 的 一 个 。

相关问题