hli*_*liu 2 constructor haskell
Network包中的PortNumber 根本没有构造函数,其定义和doc如下(或请参考https://hackage.haskell.org/package/network-2.6.2.1/docs/Network.html):
data PortNumber
Use the Num instance (i.e. use a literal) to create a PortNumber value with
the correct network-byte-ordering. You should not use the PortNum constructor.
It will be removed in the next release.
instances
...
Num PortNumber
...
Run Code Online (Sandbox Code Playgroud)
令我困惑的是它如何使用Num实例创建一个PortNumber?我知道PortNumber是类Num的一个实例,它可以被认为是一个Num,但它如何才能看到Num实例(例如文字10000)作为PortNumber?在构造具有构造函数的PortID时PortNumber PortNumber,似乎可以使用PortNumber 10000.这是怎么发生的?
如果你看一下你看到的来源:
newtype PortNumber = PortNum Word16 deriving (Eq, Ord, Typeable)
Run Code Online (Sandbox Code Playgroud)
马上.
如果您查看文档,您也会看到此警告:
DEPRECATED PortNum"不要使用PortNum构造函数.使用Num实例.将在下一版本中删除PortNum."
这里有什么意思的是,PortNumber是一个实例Num,因此你可以使用fromInteger-当它看到一个整数数字像这哈斯克尔的默认操作1,20... -这也就是为什么
Prelude> :t 666
666 :: Num a => a
Run Code Online (Sandbox Code Playgroud)
因此,您可以使用构造函数, 而不是使用构造函数,它将自动在正确的上下文中(请参阅下文)PortNum 1000010000PortNumber
对于PortId部分:PortNumber有一个构造函数PortId(参见来源:
data PortID =
Service String
| PortNumber PortNumber
| UnixSocket String
Run Code Online (Sandbox Code Playgroud)
) - 所以,如果你使用PortNumber 10000你确实正在使用Int -> PortNumber -> PortId路径,因为10000(使用fromInteger)被转换为a PortNumber然后插入构造函数 PortNumber以获得PortId
除此之外,您可能会看到带有空数据定义的示例- 但由于Haskell很懒惰,您通常仍然可以使用它undefined :: MyEmptyType来获取无论如何都不会被评估的地方的值.
使用类型函数的Fun中 有一个很好的例子:
data Zero
data Succ n
class Nat n where
toInt :: n -> Int
instance Nat Zero where
toInt _ = 0
instance (Nat n) => Nat (Succ n) where
toInt _ = 1 + toInt (undefined :: n)
Run Code Online (Sandbox Code Playgroud)