计算Enum类型的maxBound和minBound之间的差异是不可能的? [英] Is it impossible to compute the difference between the maxBound and minBound of an Enum type?

查看:271
本文介绍了计算Enum类型的maxBound和minBound之间的差异是不可能的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是否有权得出结论:无法在Haskell中为任意 Enum 计算 maxBound - minBound 并且有界类型?或者我错过了一些技巧/黑客?这是我所拥有的,显然无法工作:

 差异::(Enum a,Bounded a)=> Int 
difference = fromEnum maxBound - fromEnum minBound

Error:

  Foo.hs:37:1:
模糊约束`Enum a'
至少有一个所提到的类型变量通过约束
必须可以从'=>'
之后的类型中获得'差异'的类型签名:difference ::(Enum a,Bounded a)=> Int

Foo.hs:37:1:
不明确的约束`限制了'
约束
提及的所有类型变量中的至少一个必须可以从'=>'之后的类型到达
在'差异'的类型签名中:difference ::(Enum a,Bounded a)=> Int

我明白为什么会出现这种错误 - 在中没有实际的术语c $ c> a ,所以它不能确定 a 是什么。问题是是否有办法解决这个问题。

解决方案

使用代理 ScopedTypeVariables 来将这个类型放入函数定义的范围中。

  { - #LANGUAGE ScopedTypeVariables# - } 

数据代理a =代理

区别:: forall a。 (Enum a,Bounded a)=>代理a - > Int
差值Proxy = fromEnum(maxBound :: a) - fromEnum(minBound :: a)

>>>差异(Proxy :: Proxy Bool)
1

编辑:使用Daniel的建议:数据代理a =代理

差异::(Enum a,Bounded a)=>代理a - > Int
difference p = fromEnum(max'p) - fromEnum(min'p)其中
max'::(有界a)=>代理a - > a
max'Proxy = maxBound
min'::(有界a)=>代理a - > a
min'Proxy = minBound


Am I right to conclude that there's no way to compute maxBound - minBound in Haskell for an arbitrary Enum and Bounded type? Or am I missing some trick/hack? This is what I have, which clearly can't work:

difference :: (Enum a, Bounded a) => Int
difference = fromEnum maxBound - fromEnum minBound

Error:

Foo.hs:37:1:
    Ambiguous constraint `Enum a'
      At least one of the forall'd type variables mentioned by the constraint
      must be reachable from the type after the '=>'
    In the type signature for `difference': difference :: (Enum a, Bounded a) => Int

Foo.hs:37:1:
    Ambiguous constraint `Bounded a'
      At least one of the forall'd type variables mentioned by the constraint
      must be reachable from the type after the '=>'
   In the type signature for `difference': difference :: (Enum a, Bounded a) => Int

I understand why I'm getting that error—there's no actual term in there with type a, so it can't figure out what a is. The question is whether there's a way to get around this.

解决方案

Use a Proxy to specify which type you want, and use ScopedTypeVariables to bring that type into scope in your function definition.

{-# LANGUAGE ScopedTypeVariables #-}

data Proxy a = Proxy

difference :: forall a . (Enum a, Bounded a) => Proxy a -> Int
difference Proxy = fromEnum (maxBound :: a) - fromEnum (minBound :: a)

>>> difference (Proxy :: Proxy Bool)
1

Edit: Using Daniel's suggestion:

data Proxy a = Proxy

difference :: (Enum a, Bounded a) => Proxy a -> Int
difference p = fromEnum (max' p) - fromEnum (min' p) where
    max' :: (Bounded a) => Proxy a -> a
    max' Proxy = maxBound
    min' :: (Bounded a) => Proxy a -> a
    min' Proxy = minBound

这篇关于计算Enum类型的maxBound和minBound之间的差异是不可能的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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