首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我可以使用DerivingVia派生与元组同构的数据类型的实例吗?

我可以使用DerivingVia派生与元组同构的数据类型的实例吗?
EN

Stack Overflow用户
提问于 2022-02-21 11:18:48
回答 2查看 157关注 0票数 4

给定以下数据类型

代码语言:javascript
复制
data Both a b = Both { left :: a, right :: b }

我可以像这样为应用程序等编写实例(在这里省略函子,因为我们可以使用DeriveFunctor):

代码语言:javascript
复制
instance Monoid a => Applicative (Both a) where
    pure x = Both mempty x
    Both u f <*> Both v x = Both (u <> v) (f x)

由于Both(a,b)同构,所以我想知道是否可以使用DerivingVia派生实例:

代码语言:javascript
复制
data Both a b = ... deriving Applicative via ((,) a)

这将导致错误消息,如:

代码语言:javascript
复制
    • Couldn't match representation of type ‘(a, a1)’
                               with that of ‘Both a a1’
        arising from the coercion of the method ‘pure’
          from type ‘forall a1. a1 -> (a, a1)’
            to type ‘forall a1. a1 -> Both a a1’
    • When deriving the instance for (Applicative (Both a))

我将其解释为“编译器不知道如何将Both转换为(,)”。我如何告诉编译器使用显而易见的方法来完成这一任务?

我已经看到了这个问题和答案,但我希望有一个解决方案,需要更少的样板。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-21 11:18:48

这个答案的启发,在generic-data包的帮助下,您可以编写:

代码语言:javascript
复制
{-# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia #-}

import GHC.Generics
import Generic.Data

data Both a b = Both {left :: a, right :: b}
  deriving stock (Generic1)
  deriving (Functor, Applicative) via Generically1 (Both a)
票数 4
EN

Stack Overflow用户

发布于 2022-02-21 11:48:16

DerivingVia纸有一节介绍如何使用Generic为“通过Generic同构”的事物派生任意类。见4.3。

我觉得我已经看到了适应于一个黑客库的方法,但我现在似乎找不到它。

但是,我不确定它是否适用于您的情况,因为(a, b)和您的类型可能没有相同的Generic表示(您的类型有记录字段)。“数据类型通用手术”在这种情况下也是有用的-- https://github.com/Lysxia/generic-data-surgery#readme

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71205425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档