这是一个GHCI会议,展示了这个问题:
Prelude> import Network
Prelude Network> PortNumber 1234
PortNumber 1234
Prelude Network> let n = 1234
Prelude Network> PortNumber n
<interactive>:5:12:
Couldn't match expected type `PortNumber'
with actual type `Integer'
In the first argument of `PortNumber', namely `n'
In the expression: PortNumber n
In an equation for `it': it = PortNumber n
为什么这不起作用?鉴于存储在Integer
(或Word16
中的变量,我正在阅读用户输入,因此我可以灵活处理),为什么我不能将其传递给PortNumber
?
答案 0 :(得分:9)
正如the source所说:
newtype PortNumber = PortNum Word16 deriving (Eq, Ord, Typeable)
-- newtyped to prevent accidental use of sane-looking
-- port numbers that haven't actually been converted to
-- network-byte-order first.
换句话说,他们不希望你弄乱PortNumber
内部。 (请注意,有PortNumber
- 类型和PortNumber
- 构造函数(类型为PortID
),这有点误导。)
如果要在PortNumber
(构造函数)中使用整数变量,则必须手动将其转换为PortNumber
(类型)。幸运的是,它是Num
的一个实例,因此支持fromInteger
:
Prelude Network> let n = 234
Prelude Network> PortNumber (fromInteger n)
PortNumber 234
当您使用整数文字时,编译器会自动添加fromInteger
以使您的生活更轻松。
答案 1 :(得分:5)
Ghci不喜欢多态类型,如果函数没有签名,ghci尝试使其变为单态。
但你仍然可以写
> let n = 1234 in PortNumber n
,
> let n = 1234
> PortNumber n
<interactive>:5:12:
这是因为ghci可以帮助你提前1行,当你在gchi中添加n,n :not: Num a => a
时,它会成为n :: Integer
。 Haskell没有类型转换。因此,您还可以使用PortNumber Word16
为Integer -> Word16
(fromInteger
)进行类型转换:
>let n = 234
>PortNumber (fromInteger n)