在 Haskell 中重新排序类型参数 [英] Reordering type parameters in Haskell

查看:31
本文介绍了在 Haskell 中重新排序类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于类型参数的问题,我认为最好用一个例子来表达.这段代码

I have a question about type parameters that I think is best expressed by an example. This piece of code

newtype Triple a b c = T (a,b,c)

instance Functor (Triple a b) where
    fmap f (T (x, y, z)) = T (x, y, (f z))

将三元组表示为第三个变量中的函子.

expresses triples as functors in their third variable.

  1. 如何将它们变成第二个变量中的函子?
  2. 如何将实际的元组(不是我的新类型)转换为函子?

一般问题是:假设我有一个参数类型m a b c d e,我如何表达通过固定一个参数获得的参数类型m a b d e?或者等效地,我如何表达通过将任意参数作为最后一个获得的参数类型 m a b d e c?

The general question is: suppose I have a parametric type m a b c d e how do I express the parametric type m a b d e obtained by fixing one parameter? Or equivalently, how do I express the parametric type m a b d e c obtained by making an arbitrary parameter the last one?

我的意思可能不太清楚,所以我想澄清一下:Triple 有种 * ->* ->* ->*.所以我可以对两种类型进行部分评估以获得某种类型的 * ->* 可以是 Functor 或其他一些参数化类.这种评估在前两个参数上很容易进行,但原则上可以在任何两个参数下进行,我想知道如何完成.这实质上是要求在类型级别上进行翻转.

it may not have become quite clear what I mean, so I'm trying to clarify: Triple has kind * -> * -> * -> *. So I can partially evaluate at two types to get something of kind * -> * which could be Functor or some other parametrized class. This evaluation is easy to do at the first two parameters but it is in principle possible at any two of the parameters, and I am asking how it can be done. This is essentially asking for a flip on the level of types.

作为一个具体的用例,我可以拥有三个参数化类 Functor、Foo 和 Bar,并且我希望 (Triple _ bc) 成为一个 Functor,(Triple a _ c) 成为一个 Foo,以及 (Triple ab _) 成为 Bar(对于所有 a、b、c).那么 Triple a b c 将是一个 Functor、一个 Foo 和一个 Bar.你会想到写这些单参数类型 a ->三重 a b c, b ->三重 a b cc ->三重 a b c 但当然这个字面符号表示映射类型.

As a concrete use case I can have three parametrized classes Functor, Foo, and Bar, and I want (Triple _ b c) to be a Functor, (Triple a _ c) to be a Foo, and (Triple a b _) to be a Bar (for all a, b, c). So then Triple a b c would be a Functor, a Foo and a Bar. You would think of writing these one-parameter types a -> Triple a b c, b -> Triple a b c and c -> Triple a b c but of course this literal notation expresses mapping types.

Edit2:在 stackoverflow 上发布问题之前,我总是尝试将其剥离到其抽象核心,但这似乎掩盖了我真正想要的内容.因此,现在可以在此处找到此问题的具体变体.

Before posting a question on stackoverflow I always try to strip it to its abstract core, but this seems to obscure what I actually want. So a concrete variant of this question can now be found here.

推荐答案

在这种特定情况下,您可能会通过使用镜头获得所需的东西.

In this specific case you might get what you need by using lenses.

over<的组合/a> 和 元组模块中的所有函数(_1、_2、_3 等) 使您能够将函数提升到更多元组位置,而不仅仅是最右边的位置.

The combination of over and all the functions in the tuple module (_1, _2, _3 etc.) gives you the ability to lift functions into more tuple positions than just the rightmost one.

EDIT 添加示例.

假设我们有这个元组.

(1, "Foo", True)

我们希望 (+ 1) 到第一个位置的值.

And we want to (+ 1) to the value in its first position.

> import Control.Lens (over, _1)
> over _1 (+ 1) (1, "Foo", True)
(2,"Foo",True)

或者将字符串的第二个位置大写

Or upper-case the string in its second position

> import Data.Char (toUpper)
> import Control.Lens (over, _2)
> over _2 (map toUpper) (1, "Foo", True)
(1,"FOO",True)

或者我们想将布尔值翻转到第三个位置

Or perhaps we want to flip the bool in its third position

> import Control.Lens (over, _3)
> over _3 not (1, "Foo", True)
(1,"Foo",False)

这篇关于在 Haskell 中重新排序类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆