如果有足够耐心的人向我解释以下情况,我将非常感激。在我看来,Haskell 已经准备好在从函数返回值时执行某种整数类型强制转换。另一方面,我读过 Haskell 从不隐式转换类型。
如果我输入 GHCi:
> import Data.Word
> let t :: (Integer, Word32);
t = let { y = fromIntegral (-1) -- line breaks added for readability
; y' :: Integer
; y' = fromIntegral y } in (y', y)
GHCi 后来告诉我
t = (-1,4294967295)
.但是如果我约束本地 y
专门输入 Word32
:> let t :: (Integer, Word32);
t = let { y :: Word32
; y = fromIntegral (-1) -- line breaks added for readability
; y' :: Integer
; y' = fromIntegral y } in (y', y)
GHCi 会告诉我
t = (4294967295,4294967295)
.我以为如果
t
的类型明确表示为 (Integer, Word32)
, GHCi 将得出结论 y' :: Integer
和 y :: Word32
因为函数结果是 (y', y)
.然后,类型定义 y :: Word32
完全没有必要。当我尝试编写一个函数以在 Integral 类成员之间“安全地”转换时,这一切都开始了 - 例如整数 -> Word32。该函数旨在返回
Just 1
通过时 1
和 Nothing
通过时 -1
.通过 SO 和互联网进行的简短搜索并没有为我提供任何解释。
最佳答案
I thought that if
t
's type is stated explicite as(Integer, Word32)
, GHCi will conclude thaty' :: Integer
andy :: Word32
since the function result is(y', y)
.
不,它不会推断出有关
y'
的类型的任何信息。和 y
.它只是检查它们是否与预期的类型兼容。一个更简单的例子1:x = -1
y :: Integer
y = x
y' :: Word32
y' = x
x
是哪种类型的有?都不是 Integer
也不是 Word32
.这是type of literals :x :: Num a => a
x = fromInteger (-1 :: Integer)
和
Num a => a
与 Integer
的用法兼容在 y
并作为 Word32
在 y'
.怎么样都没关系x
使用,类型为x
仅取决于该术语的定义方式。为了解释您的结果,请记住引用透明度——我们可以用它们的定义替换变量:
t = let y = fromIntegral (-1)
y' = (fromIntegral y) :: Integer
in (y', y) :: (Integer, Word32)
扩展到
t = ( (fromIntegral (fromIntegral (-1))) :: Integer -- nothing says Word32 here
, fromIntegral (-1)
) :: (Integer, Word32)
而第二个
t = let y = (fromIntegral (-1)) :: Word32
y' = (fromIntegral y) :: Integer
in (y', y) :: (Integer, Word32)
扩展到
t = ( (fromIntegral ( (fromIntegral (-1)) :: Word32 )) :: Integer
, (fromIntegral (-1)) :: Word32
) :: (Integer, Word32)
1:希望dreaded monomorphism restriction不会在这里惹我们。任何更有知识的人都可以确认它不适用于
x
(或在什么情况下)?
关于haskell - 未强制执行函数返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45634776/