Haskell 中的强制多参数类型

发布于 2024-12-02 11:55:31 字数 855 浏览 0 评论 0原文

我有一个类型

class IntegerAsType a where
  value :: a -> Integer

data T5
instance IntegerAsType T5 where value _ = 5

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]

我的主要问题是:如何在特定的 PolyRing 中定义变量?

应该是这样的:(

x = [1, 2, 3] :: Integer T5

我认为) 问题是::: 之后的正确语法是什么?

我收到错误

Couldn't match expected type `PolyRing Integer T5'
         with actual type `[t0]'
In the expression: [1, 2, 3] :: PolyRing Integer T5
In an equation for `x': x = [1, 2, 3] :: PolyRing Integer T5

此外,我正在寻找更好的方法来实现此目的。特别是,我真的希望从列表元素的类型推断出类型 a ,而必须指定 IntegerAsType n (它不应该依赖于列表的长度,即使这是可能的)。

到目前为止我尝试过的事情:

x = [1,2,3] :: PolyRing (Integer, T5)

x = [1,2,3] :: PolyRing Integer T5

I have a type

class IntegerAsType a where
  value :: a -> Integer

data T5
instance IntegerAsType T5 where value _ = 5

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]

My main question is: how do I define a variable in a particular PolyRing?

It should be something like:

x = [1, 2, 3] :: Integer T5

(I think)
The question is: what is the correct syntax after the ::?

I'm getting the error

Couldn't match expected type `PolyRing Integer T5'
         with actual type `[t0]'
In the expression: [1, 2, 3] :: PolyRing Integer T5
In an equation for `x': x = [1, 2, 3] :: PolyRing Integer T5

Also, I'm looking for a better way to implement this. In particular, I'd really like for the type a to be inferred from the type of list elements, while the IntegerAsType n must be specified (it shouldn't depend on the length of the list, even if that is possible).

Things I've tried so far:

x = [1,2,3] :: PolyRing (Integer, T5)

x = [1,2,3] :: PolyRing Integer T5

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

×眷恋的温暖 2024-12-09 11:55:31

首先注意

数据类型上下文,例如:

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]

通常是一个坏主意,并且已从该语言中退役。

忽略这一点

要构造一个实例,您必须使用数据构造函数 PolyRing

PolyRing [1,2,3]

但这还不够,到目前为止的类型推断将为 (IntegerAsType n) = > PolyRing 整数 n。您的最终类型签名将完成此操作 let x = PolyRing [1,2,3] :: PolyRing Integer T5

回到第一个注释

不过,也许您想要:

newtype PolyRing a n = PolyRing [a]

每个构建或使用多环的函数都可以强制执行所需的约束:

func :: (Num a, IntegerAsType n) => PolyRing a n -> ...

First Note

Data type contexts, such as:

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]

are generally a bad idea and have been retired from the language.

Ignoring That

To construct an instance you must use the data constructor PolyRing:

PolyRing [1,2,3]

But that isn't enough, the type inference so far will be (IntegerAsType n) => PolyRing Integer n. Your final type signature would finish this up let x = PolyRing [1,2,3] :: PolyRing Integer T5.

Returning To the First Note

Still, perhaps you wanted:

newtype PolyRing a n = PolyRing [a]

And every function that builds or consumes a polyring can enforce the needed constraints:

func :: (Num a, IntegerAsType n) => PolyRing a n -> ...
空心空情空意 2024-12-09 11:55:31

newtype 不仅仅是一个同义词,而且是一种创建在类型级别上不同的类型的方法(尽管稍后相同)。也就是说 - 您需要使用数据构造函数显式包装它。此外,上下文也没有影响。您仍然必须到处输入它。

A newtype is not just a synonym but a way to create a type that is distinct at the type level (though identical later). That said - you need to wrap it explicitly using your data constructor. Also, the context has no effect. You still have to type it everywhere.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文