gpt4 book ai didi

Haskell,在函数内将 Int 和 Float 相乘

转载 作者:行者123 更新时间:2023-12-02 08:59:55 24 4
gpt4 key购买 nike

为什么在ghci中我可以输入:

5.0 * (3 - 1)
> 10.0

但是如果我尝试在 .hs 文件中创建一个函数并将其加载到:

test :: Float -> Int -> Int -> Float
test a b c = a * (b - c)

我遇到了错误? “无法将预期类型“Float”与推断类型“Int”进行匹配?我怎样才能编写一个接受 1 个浮点和 2 个整数参数并对它们执行上述操作的函数?

我正在使用 ghci v6.12.1,如果这有什么不同的话......

最佳答案

数字文字(即仅在 Haskell 代码中键入数字)不是某种固定类型。它们是多态的。它们需要在某些需要它们具有具体类型的上下文中进行评估。

因此,表达式5.0 * (3 - 1)不是Int乘以Float5.0 必须是某种 Fractional 类型,31 分别是一些 Num类型。 3 - 1 表示 3 和 1 必须是相同 Num 类型,但我们仍然没有(还)有关于它是哪一个特定的任何更多限制;相减的结果是相同的类型。

* 意味着两个参数必须是相同的类型,并且结果也将是相同的类型。由于 5.0 是某种 Fractional 类型,因此 (3 - 1) 也必须如此。我们已经知道 31(3 - 1) 必须是某种 Num 类型,但所有这些Fractional 类型也是 Num 类型,因此此要求并不冲突。

最终结果是整个表达式 5.0 * (3 - 1) 是某种 Fractional 类型,并且 5.031 都是同一类型。您可以在 GHCi 中使用 :t 命令来查看:

Prelude> :t 5.0 * (3 - 1)
5.0 * (3 - 1) :: Fractional a => a

但要实际评估该表达式,我们需要对某些具体类型进行评估。如果我们正在评估它并将其传递给需要 Float、Double 或其他特定的 Fractional 类型的函数,那么 Haskell 会选择那个类型。如果我们只是评估表达式,没有其他上下文要求它是特定类型,Haskell 有一些默认规则来自动为您选择一个(如果默认规则不适用,它将给您一个关于不明确类型变量的类型错误)。

Prelude> 5.0 * (3 - 1)
10.0
Prelude> :t it
it :: Double

上面我已经评估了 5.0 * (3 - 1),然后询问了魔法 it 变量的类型,GHCi 始终将其绑定(bind)到它评估的最后一个值。这告诉我,GHCi 将我的 Fractional a => a 类型默认为 Double,以便计算表达式的值为 10.0 >。在进行该计算时,它仅乘以(并减去)Double,而从未将 Double 乘以 Int

<小时/>

现在,当您尝试使用多个看起来可能具有不同类型的数字文字时,就会发生这种情况。但是您的 test 函数不是乘以文字,而是乘以特定已知类型的变量。在 Haskell 中,您不能将 IntFloat 相乘,因为 * 运算符的类型为 Num a => a -> a -> a - 它采用两个相同数字类型的值并给出该类型的结果。您可以将 Int 乘以 Int 得到 Int,或者将 Float 乘以 Float 来获取Float。您不能将 Int 乘以 Float 来得到 ???

其他语言仅通过在某些情况下隐式插入对转换函数的调用来支持此类操作。 Haskell 从不在类型之间隐式转换,但它具有转换函数。如果您希望调用它们,您只需要显式调用它们即可。这可以解决问题:

test :: Float -> Int -> Int -> Float
test a b c = a * fromIntegral (b - c)

关于Haskell,在函数内将 Int 和 Float 相乘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19019093/

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