在值构造函数中指定类约束 [英] Specifying class constraints in value constructors

查看:219
本文介绍了在值构造函数中指定类约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种方法可以为值构造函数的参数定义类约束?



类似这样:

  data Point2D =(Num a)=> Point aa 

,以便Point可以接受任何参数,只要它们属于Num类?您可以使用 ExistentialQuantification GADTs

code>,但两者都不会做你想要的。你永远不能用两个 Point2D 值进行算术。所有你知道的内容是,他们是一些 Num的实例。你告诉编译器放弃关于它们的所有其他信息。这意味着你告诉编译器丢弃任何信息,特定的 Point2D 值包含相同的类型。没有这些信息,你将不能对来自两个 Point2D 的值进行任何算术。



这几乎肯定不是你想要的。例如,您不能写 distance 函数。你对这种有限类型可能有什么用?关于你所有你可以做的是将它们的内容转换为 String



编辑:



我想我看到你想做什么。你只是想确保Point2D中的一切都是一个数字。



在这种情况下,我会使用GADT版本,一个非常重要的更改:

  { - #LANGUAGE GADTs# - } 
data Point2D a where
Point ::(Num a)=> a - > a - > Point2D a

其最终结果是只能使用 构造函数具有两个相同的Num实例的值,但是你不会失去什么类型。此外,由于使用 GADTs ,在 Point 构造函数上的模式匹配恢复了你的Num上下文,你会期望什么。



但我认为这里最重要的是不丢弃内容的类型。这样做使得类型基本上不可能使用。


Is there a way to define a class constraint for a value constructor's parameter?

Something like this:

data Point2D = (Num a) => Point a a

so that Point can take any arguments as long as they belong to the Num class?

解决方案

You can use ExistentialQuantification or GADTs, but neither is going to do what you want. You'll never be able to do arithmetic with two Point2D values. All you know about the contents is that they're some instance of Num. You're telling the compiler to discard all other information about them. This means you're telling the compiler to discard any information it may have that a particular pair of Point2D values contain the same type. And without that information, you won't be able to do any arithmetic on values from two Point2Ds together.

This almost certainly isn't what you want. You can't write a distance function, for instance. What possible use could you have for such a limited type? About all you can do with them is convert their contents to a String.

Edit:

I think I see what you're trying to do. You just want to ensure that everything in a Point2D is a number. I don't think you actually want type erasure.

In that case, I'd go with the GADT version, with one really important change:

{-# LANGUAGE GADTs #-}
data Point2D a where
    Point :: (Num a) => a -> a -> Point2D a

The end result of this is that you can only use the Point constructor with two values of the same instance of Num, but you don't lose what the type was. Furthermore, thanks to using GADTs, pattern-matching on the Point constructor recovers the Num context for you, which is basically what you'd expect.

But I think the most important thing here is not throwing away the type of the contents. Doing so makes the type basically impossible to work with.

这篇关于在值构造函数中指定类约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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