2012-04-17 77 views
8

请注意GHCi会话中的第二行。什么是Latitude类型,允许我使用“裸”数字作为值,而不必调用构造函数?我想用我自己的一些类型做类似的事情。将“裸”数字分配给新类型

λ> :m + Data.Geo.GPX.Type.Latitude                         
λ> let t = 45 :: Latitude                            
λ> t                                 
45.0 

我已经检查了Latitude类型的源代码,但是我一开始就遇到了麻烦。最终我找到了答案,所以我想我会在这里记录它。请参阅下面的答案。

回答

4

根据Haskell98标准,数字文字实际上是对fromIntegerfromRational的调用。这可以将它们转换为实现这些功能的任何类型(fromInteger位于Prelude.Num类型类中,而fromRational位于Prelude.Fractional类型类中)。

数字文字的语法在2.5节给出。一个整数 literal代表从Integer到 Integer类型的适当值的函数应用。同样,浮点文字 代表fromRational到类型Rational (即比例整数)的值的应用。鉴于分型:

fromInteger ::(民一)=>整数 - >一个

fromRational ::(分数A)=>理性 - >一个

整数和浮点数文字具有分型( Num a)=> a和 (分数a)=> a。数字文字在这种间接方式中定义为 ,以便它们可以被解释为任何适当的数字类型的值。有关 超载模糊的讨论,请参见第4.3.4节。

http://www.haskell.org/onlinereport/basic.html#numeric-literals

6

是什么使这项工作是该类型是一个数字。最简单的方法是使用“派生Num”,在这种情况下,我需要语言杂注GeneralizedNewtypeDeriving。因此,我可以创造一个请键入以下,

newtype Seconds = Seconds Double deriving (Eq, Ord, Enum, Num, Fractional, Floating, Real, RealFrac, RealFloat, Show) 

然后在GHCI,

λ> let s = 5 :: Seconds                            
λ> s                                 
Seconds 5.0 

或者,我可以明确地实现民。

+4

确切的说,这是一个事实,即'Seconds'是在'Num'类,使得它的工作。无论它如何成为'Num'类的成员并不重要。 – augustss 2012-04-17 13:09:55

+2

如果明确提供实例而不是派生实例,它也可以工作。所有你需要的是一个'实例Num'。 – 2012-04-17 13:10:09

+0

谢谢奥古斯特和丹尼尔。我已经更新了答案。 – mhwombat 2012-04-17 13:20:57

相关问题