在Haskell中,是否有一种编写num-to-num转换函数的好方法`toNum::(num a,num b)=>;a->;b`?

在Haskell中,是否有一种编写num-to-num转换函数的好方法`toNum::(num a,num b)=>;a->;b`?,haskell,numbers,typeclass,Haskell,Numbers,Typeclass,例如,一种不好的方法是通过字符串进行因子分析: toReadableNum :: (Num a, Num b, Read b) => a -> b toReadableNum = read . show 如果没有好方法,还有其他坏方法吗?具体实施?需要语言扩展吗?没有好办法。有些数字比另一些数字包含更多的信息,所以你怎么能期望以一种好的方式在两个任意数字之间进行转换呢。一些简单的例子:如何将Double转换为Int?Int8上的一个理性的选择?一个复杂的双精度浮点数 所有这些都涉及

例如,一种不好的方法是通过字符串进行因子分析:

toReadableNum :: (Num a, Num b, Read b) => a -> b
toReadableNum = read . show

如果没有好方法,还有其他坏方法吗?具体实施?需要语言扩展吗?

没有好办法。有些数字比另一些数字包含更多的信息,所以你怎么能期望以一种好的方式在两个任意数字之间进行转换呢。一些简单的例子:如何将Double转换为Int?Int8上的一个理性的选择?一个复杂的双精度浮点数

所有这些都涉及到信息的丢失,并且没有明显的正确方法



正如@hammar所说,
Num
中的操作根本不允许您构造这样的函数。

好的方法是进行特定类型的转换,如圆形或钳形。这样的函数按照它所说的做。

您不能编写任何类型的有用函数
(Num a,Num b)=>a->b
。由于
a
b
是类型变量,因此我们只能对它们使用
Num
类中的操作。(
Eq
Show
在这里对我们帮助不大)

这里唯一允许您创建
b
的函数是
fromInteger
,如果您没有这样的函数,但是您无法将
a
转换为
Integer
,因此您可以编写的此类函数只能返回某个常量或底部的
fromInteger
。不是很有用


因此,无论如何,没有明显的方法进行这种转换。请记住,许多类型可以是
Num
。不仅是各种类型的实数,还有复数、矩阵、多项式等。它们之间没有任何有意义的转换。

你不能(正常地)从
Num
转换到
Num
,由于Num除了其虚假的Eq和Show机制之外,没有提供任何机制来提取关于所持有价值的信息,但是如果您愿意代表您来自的数字假设更多的信息,那么您可以拥有追索权

特别是

fromIntegral :: (Integral a, Num b) => a -> b
以及

toRational :: Real a => a -> Rational

两人都是很好的候选人,都能胜任你的工作,即使不是你所要求的

读取时。show
打字准确,具有您提议的签名,意思是gobbledigook。没有任何证据表明一个
Show
实例发出的文本将与一个完全不同的
Read
实例兼容,而且还有很多反例

Read
Show
上的(隐含)合同仅在您将其用于相同类型时适用

toRational :: Real a => a -> Rational
fromRational :: Fractional a => Rational -> a