函数返回类型未强制执行

时间:2017-08-11 12:02:24

标签: haskell types functional-programming polymorphism type-coercion

如果有耐心的人向我解释下面的情况,我将非常感激。在我看来,好像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' :: Integery :: Word32,因为函数结果为(y', y) 。然后,类型定义y :: Word32将完全没必要。

当我尝试编写一个函数来“安全地”在Integral类成员之间进行转换时,这一切都开始了 - 例如Int - > Word32。该函数旨在通过Just 1时传递1,传递Nothing时传递-1

通过搜索引擎优化和互联网进行的简短搜索并未向我提供任何解释。

1 个答案:

答案 0 :(得分:7)

  

我认为如果t的类型明确表示为(Integer, Word32),GHCi会得出y' :: Integery :: Word32,因为函数结果为(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 => aInteger中的yWord32中的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(或在什么情况下)?