Haskell:来自这种数据类型的仿函数?

标签 haskell functor

抱歉,标题不好。我有一个有问题的数据类型,我试图将其定义为仿函数的实例。

所以基本上,我所拥有的是一些东西

sample_logp :: s a -> a

并且应该使用它进行转换

(a -> b)

sample_logp :: s b -> b

。下面的代码并没有完全实现这一点,并且仅在

sample_logp :: s a -> b  

.

data Model s a = Model {
  sample_logp :: s a -> a
}

instance Functor (Model s) where
  fmap f m = Model {
    sample_logp = sample_logp'
  } where sample_logp' x = (f . (sample_logp m)) x

我正在尝试的事情可能吗?如果是这样,如何更新此代码以实现此目的?

最佳答案

这里的标准方法是添加更多类型变量。

data Model s a b = Model {
  sample_logp :: s a -> b
}

拆分类型变量后,您可以使用更多工具。 Profunctor类在这里是合适的。 (没有进行类型检查,因为我在这个系统上没有 ghc - 如果我的实现关闭,请发表评论或修复它。)

instance (Functor s) => Profunctor (Model s) where
    dimap f g (Model h) = Model $ g . h . fmap f
    lmap f (Model h) = Model $ h . fmap f
    rmap g (Model h) = Model $ g . h

现在,假设您有一个 Model s a a,它相当于您的 Model s a,您可以将其转换为 Model s b b > 通过使用 dimap bToA aToB

正如评论所说,您的原始数据类型是不变的,因为它在正数和负数位置使用相同的类型变量。这意味着您需要提供每个方向的转换函数。添加额外的类型变量可以让您利用现有工具来实现此目的,例如 Profunctor

<小时/>

请注意,以上所有内容均基于您对 s 使用协变类型的假设。如果 s 是逆变的,那么您可以为原始类型编写一个直接的 Functor 实例,如 chi 的评论所述。不过,这种情况不太常见。

关于Haskell:来自这种数据类型的仿函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36262016/

相关文章:

haskell - 如何连接两个 Haskell IO monad

haskell - Haskell 中的文学编程真的是 "literate programming"吗?

haskell - 将 `Functor` 类泛化为 `MultiFunctor`?

Python:将全局对象声明为实例变量

c++ - 这是文档中的一个小错误还是我遗漏了什么?

haskell - 在 ghc-7.6.1 之后的世界中,DynamicException 等价物是什么?

haskell - 初始化标准中的基准并从结果中排除初始化时间

haskell - 如何在 IO 上下文中生成一个函数对其先前结果的重复应用列表

c++ - 在不创建 Functor 类的情况下使用 Functors 时出错?

模块和记录字段