在Haskell中,有一种很好的方法可以将num写入num转换函数`toNum ::(Num a,Num b)=> a - > B`?

时间:2011-07-23 06:48:50

标签: haskell numbers typeclass

例如,一种不好的方法是通过字符串:

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

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

4 个答案:

答案 0 :(得分:7)

没有好办法。有些数字包含更多其他数据,所以你怎么能期望以一种好的方式在两个任意数字之间进行转换。一些简单的例子:如何将Double转换为Int?对Int8有理由吗?一个复杂的双重浮动?

所有这些都涉及信息丢失,然后没有明显的正确方法。


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

答案 1 :(得分:7)

你不能(明智地)从NumNum,因为Num没有提供任何机制来提取除了它的虚假Eq和Show机器之外的值,但是如果你愿意的话代表您来自的号码,假设更多,那么您可以追索。

特别是

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

的组成
toRational :: Real a => a -> Rational

fromRational :: Fractional a => Rational -> a
如果不是你要求的话,

都是做你意思的好人选。

虽然read . show输入得很好且有你提出的签名,但意思是gobbledigook。没有什么可以说一个Show实例发出的文本将与完全不同的Read实例兼容,并且有很多反例。

ReadShow上的(隐含)合同仅适用于您使用相同类型的合同!

答案 2 :(得分:3)

您无法编写(Num a, Num b) => a -> b类型的任何有用功能。由于ab是类型变量,因此我们可以在其上使用的唯一有用的操作是Num类中的操作。 (EqShow在这里对我们没什么帮助。)

class  (Eq a, Show a) => Num a  where
    (+), (-), (*)       :: a -> a -> a
    negate              :: a -> a
    abs                 :: a -> a
    signum              :: a -> a
    fromInteger         :: Integer -> a

此处唯一允许您制作b的功能,如果您没有fromIntegera,则无法将Integer转换为fromInteger {1}},因此您可以编写此类型的唯一函数返回某个常量或底部的Num。不太有用。


作为augustss pointed out,无论如何都没有明显的方法进行此转换。请记住,许多类型可以是{{1}}。不仅是各种类型的实数,还有复数,矩阵,多项式等。没有任何有意义的转换可以在所有实数之间起作用。

答案 3 :(得分:0)

好方法是进行特定类型的转换,例如圆形或钳形。这样的功能就像它所说的那样。