gpt4 book ai didi

Haskell 类型强制

转载 作者:行者123 更新时间:2023-12-02 16:06:47 26 4
gpt4 key购买 nike

我试图理解 Haskell 类型的强制转换。意思是,什么时候可以在不进行强制转换的情况下将值传递给函数以及它是如何工作的。这是一个具体的例子,但我正在寻找一个更一般的解释,我可以用它来尝试理解正在发生的事情:

Prelude> 3 * 20 / 4
15.0
Prelude> let c = 20
Prelude> :t c
c :: Integer
Prelude> 3 * c / 4

<interactive>:94:7:
No instance for (Fractional Integer)
arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Integer)
In the expression: 3 * c / 4
In an equation for `it': it = 3 * c / 4

(/) 的类型是小数 a => a -> a -> a。所以,我猜测当我使用文字执行“3 * 20”时,Haskell 以某种方式假设该表达式的结果是一个分数。但是,当使用变量时,它的类型根据赋值预定义为 Integer。

我的第一个问题是如何解决这个问题。我是否需要强制转换表达式或以某种方式转换它?我的第二个问题是,这对我来说真的很奇怪,你不能在不担心 int/float 类型的情况下进行基本数学。我的意思是有一种明显的方法可以在这些之间自动转换,为什么我被迫考虑这个并处理它?我一开始就做错了什么吗?

我基本上正在寻找一种方法来轻松编写简单的算术表达式,而不必担心整洁的细节并保持代码的美观和干净。在大多数顶级语言中,编译器都适合我——而不是相反。

最佳答案

如果你只是想要解决方案,请看最后。

你几乎已经回答了你自己的问题。 Haskell 中的文字是重载的:

Prelude> :t 3
3 :: Num a => a

因为(*)也有一个Num约束

Prelude> :t (*)
(*) :: Num a => a -> a -> a

这延伸到产品:

Prelude> :t 3 * 20
3 * 20 :: Num a => a

因此,根据上下文,可以将其专门化为 IntIntegerFloatDouble 类型code>、Rational 等,根据需要。特别是,由于 FractionalNum 的子类,因此可以在除法中毫无问题地使用它,但随后约束将变为更强并且适用于类 Fractional:

Prelude> :t 3 * 20 / 4
3 * 20 / 4 :: Fractional a => a

最大的区别是标识符c是一个Integer。 GHCi 提示符中的简单 let 绑定(bind)未分配重载类型的原因是可怕的 monomorphism restriction 。简而言之:如果您定义一个没有任何显式参数的值,那么除非您提供显式类型签名,否则它不能具有重载类型。数字类型默认为Integer

一旦cInteger,乘法的结果也是Integer:

Prelude> :t 3 * c
3 * c :: Integer

并且Integer 不在Fractional 类中。

这个问题有两种解决方案。

  1. 确保您的标识符也具有重载类型。在这种情况下,它会 就这么简单地说

      Prelude> let c :: Num a => a; c = 20
    Prelude> :t c
    c :: Num a => a
  2. 使用 fromIntegral 将整数值转换为任意数值:

      Prelude> :t fromIntegral
    fromIntegral :: (Integral a, Num b) => a -> b
    Prelude> let c = 20
    Prelude> :t c
    c :: Integer
    Prelude> :t fromIntegral c
    fromIntegral c :: Num b => b
    Prelude> 3 * fromIntegral c / 4
    15.0

关于Haskell 类型强制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14667662/

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