gpt4 book ai didi

Haskell:通过 `fromIntegral` 了解类型转换机制

转载 作者:行者123 更新时间:2023-12-02 20:41:58 25 4
gpt4 key购买 nike

通过 fromIntegral 理解类型转换

所以,我最近遇到了很多类型转换错误。这让我开始使用 fromIntegral,尽管我对它的工作方式感到非常困惑。

minimalExample :: Integer -> Integer
minimalExample a = truncate y
where
x = fromIntegral (a + 10)
y = x - 12 * (x / 13)

请注意我如何使用 fromIntegral 来确保 x(/) 运算符的正确类型。如果 x 是 Integral 类型,则它不会起作用。对 GHCI 中函数的类型检查为我提供了以下信息:

Prelude> :t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b

Prelude> :t (/)
(/) :: Fractional a => a -> a -> a

显然 fromIntegralInt/Integer 转换为某种 Num 类类型(哪一个?我没有主意)。除法中缀运算符需要两个小数作为输入。现在看看this graphic ,它总结了 Haskell 中的标准类型-类关系。

Num 位于 Fractional 之上,这意味着并非每个 Num-Type 都是 Fractional。那么为什么 (/) 接受通用 Num 类型作为参数?

我认为这是因为 fromIntegral 并没有真正转换为 Num (那些甚至不能实例化,是吗?只能由具体类型继承),但是相反,它直接转换为 DoubleFloat

如果是这样,它实际上会转换为哪一个?为什么它实际上不在其定义中列出该具体类型,而是列出模糊且通用的 Num 类类型?

最佳答案

fromIntegral 不会转换为某种模糊的不可知的 Num 类型。它会转换为所需的内容。也就是说,fromIntegral 不选择自己的结果类型;而是选择它自己的结果类型。调用者这样做。所以

fromIntegral :: Int -> Integer
fromIntegral :: Int -> Word
fromIntegral :: Integer -> Double

等等。在这种情况下,类型检查器推断

minimalExample :: Integer -> Integer
minimalExample a = truncate y
where
x, y :: Fractional n => n
x = fromIntegral (a + 10)
y = x - 12 * (x / 13)

因为 (/) 需要 Fractional 类型。

然后默认机制启动来修复n:

minimalExample :: Integer -> Integer
minimalExample a = truncate y
where
x, y :: Double
x = fromIntegral (a + 10)
y = x - 12 * (x / 13)

你可能会期望结果是这样

minimalExample :: Integer -> Integer
minimalExample a = truncate (y :: Double)
where
x, y :: Fractional n => n
x = fromIntegral (a + 10)
y = x - 12 * (x / 13)

我当然做到了!但事实并非如此。可怕的单态限制开始起作用,并强制 xy 在受约束类型 n 中是单态的,因为它们不是(语法上)函数。是的,单态限制很奇怪。

关于Haskell:通过 `fromIntegral` 了解类型转换机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55525407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com