Pet*_*fel 3 haskell type-conversion
我刚刚开始学习Haskell for Great Good,我在类型类方面遇到了一些麻烦.我想创建一个采用任何数字类型的函数,并强制它为double.
我的第一个想法是定义
numToDouble :: Num -> Double
Run Code Online (Sandbox Code Playgroud)
但我不认为这有效,因为Num它不是一个类型,它是一个类型类(在我看来它是一组类型).所以,看read,表明(Read a) => String -> a.我正在阅读它,因为"read接受一个字符串,并返回一个a由用户指定的类型".所以我写了以下内容
numToDouble :: (Num n) => n -> Double
numToDouble i = ((i) :: Double)
Run Code Online (Sandbox Code Playgroud)
这对我来说就像"接受类型为n的东西(必须在Num类型类中,并将其转换为Double".这似乎是合理的,因为我能做到20::Double
这会产生以下输出
Could not deduce (n ~ Double)
from the context (Num n)
bound by the type signature for numToDouble :: Num n => n -> Double
Run Code Online (Sandbox Code Playgroud)
我不知道我在读什么.基于我能找到的,似乎这与多态性有关?
编辑:
要明确的是,我的问题是:为什么这不起作用?
您可以说"20 :: Double"的原因是在Haskell中,整数文字的类型为"Num a => a",这意味着它可以是您喜欢的任何数字类型.
你是对的,类型类是一组类型.确切地说,它是在类型类的"where"子句中实现函数的一组类型.numToDouble的类型签名正确表达了您要执行的操作.
您在函数中对"n"类型值的所有了解都是它实现了Num接口.它由+, - ,*,negate,abs,signum和fromInteger组成.最后一个是唯一一个进行类型转换,但它没有任何用途你想要的.
请记住,Complex也是Num的一个实例.numToDouble应该怎么做?正确的事情并不明显,这是你遇到问题的部分原因.
但是,在类型层次结构中,您可以使用Real类型类,它具有您可能想要使用的所有更简单的数字类型的实例,例如浮点数,双精度数和各种类型的整数.这包括一个功能"toRational",这将任何真正的价值成比例,从中可以将其转换为双用"fromRational",这是"分数"类型类的功能.
所以尝试:
toDouble :: (Real n) => n -> Double
toDouble = fromRational . toRational
Run Code Online (Sandbox Code Playgroud)
但当然这实际上太具体了.GHCI说:
Prelude> :type fromRational . toRational
fromRational . toRational :: (Fractional c, Real a) => a -> c
Run Code Online (Sandbox Code Playgroud)
所以它转换为任何实际类型的任何分数类型(后者包括任何可以做的划分,包括那都不算事的真实情况,如复杂的)当与数字类型乱搞我一直发现自己使用它作为一种通用的数值的强迫.
编辑:左撇子说,
realToFrac = fromRational . toRational
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1331 次 |
| 最近记录: |