haskell - 为什么在这个函数的类实例中不能接受这个保留结构的 "fmap"?

标签 haskell functor category-abstractions

下面定义的函数 ma​​pRightR 仅更改 map 的设置内容,而不更改键并生成有效的关系类型。

是真的不能使用这个高级函数来定义 Functor Relation 实例,还是我的实现有误。

{-# LANGUAGE GADTs #-}

import Data.Map as M
import Data.Set as S

data Relation a b where
    R :: (Ord a, Ord b) => Map a (Set b) -> Relation a b

instance Functor Relation where
    fmap f r = mapRightR f r

mapRightR :: Ord b1 => (b2 -> b1) -> Relation a b2 -> Relation a b1
mapRightR f (R r) = R $ M.map (S.map f) r

谢谢,chepner

我尝试了关系的另一种定义,使用 List 而不是 Set,它起作用了!

data Relation a b where
    R :: (Ord a) => Map a [b] -> Relation a b

instance Functor (Relation a) where
    fmap f r = mapRightR f r

mapRightR :: (b2 -> b1) -> Relation a b2 -> Relation a b1
mapRightR f (R r) = R $ M.map (L.map f) r

最佳答案

mapRightR 受到限制,它不适用于 任何 类型 b,因为 fmap 要求:

-- Specialized for f ~ Relation c
fmap ::               (a -> b) -> Relation c a -> Relation c b

但是

mapRightR :: Ord b => (a -> b) -> Relation c a -> Relation c b

用更明确的术语来说,Relation c 不是将 Hask 映射到 Hask 的内仿函数(Functor typeclass represents),而是一个仿函数,它将 Hask 的子类别映射到 Hask,该子类别仅包含具有 Ord 实例的类型。 (我想我的描述是正确的;欢迎指正。)

关于haskell - 为什么在这个函数的类实例中不能接受这个保留结构的 "fmap"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56281416/

相关文章:

Haskell 多重仿函数

haskell - Semigroupoid 和 Semigroup 类之间的关系

haskell - 使用类别的 Functor 进行映射

haskell - 在 append 下保持 IO 惰性

haskell - haskell中有没有一种方法可以通过多个参数和不同的顺序进行紧凑有效的比较

function - Haskell showFFloat 的第三个参数

haskell - Control.Category,>>>和<<<是什么意思?

haskell - Haskell 中 PETSc FFI 的库设计

c++ - 使用全局变量和仿函数实现日志记录

Haskell 双链表仿函数