Haskell 将一个数字提高到分数(数据比率)幂?

Haskell 将一个数字提高到分数(数据比率)幂?,haskell,types,ghci,exponentiation,Haskell,Types,Ghci,Exponentiation,像2^(2%1)这样的表达式不会在GHCi中进行类型检查,并且错误消息是隐藏的。为什么这不起作用,我需要改变什么 我无法转换为其他类型,我希望将其用于表达式,如27^(1%3)Haskell有三个幂运算符: (^):(数值a,整数b)=>a->b->a 这将使用正整数指数引发任何类型的数字 键入2^(2%3)时,由于使用“^”(2%3)而导致出现类似无法推断(积分(比率a0))的错误,因为数据。比率不是积分的实例。GHC发现^需要积分并注意数据。在这种情况下,不能使用比率 (^^)::(分数a,

2^(2%1)
这样的表达式不会在GHCi中进行类型检查,并且错误消息是隐藏的。为什么这不起作用,我需要改变什么

我无法转换为其他类型,我希望将其用于表达式,如
27^(1%3)

Haskell有三个幂运算符:

  • (^):(数值a,整数b)=>a->b->a

    这将使用正整数指数引发任何类型的数字

    键入
    2^(2%3)
    时,由于使用“^”(2%3)而导致出现类似
    无法推断(积分(比率a0))的错误,因为
    数据。比率
    不是
    积分的实例。GHC发现
    ^
    需要
    积分
    并注意
    数据。在这种情况下,不能使用比率

  • (^^)::(分数a,积分b)=>a->b->a

    此运算符允许负积分指数。请记住
    x^(-n)==1/(x^n)
    。这就是为什么它需要
    分数

    请注意,指数仍然必须是整数<代码>2^^(1%2)
    不是
    分数

  • (**)::浮动a=>a->a->a

    这是“一网打尽”的操作员。它可以将一个分数提高到分数次幂。然而,它使用的是浮点数,而不是精确的有理数

  • 因为我们不能代表所有的实数,所以当你需要不精确的运算时,他们决定简单地依靠浮点数

    因此,您应该使用类型转换来执行该操作A可能的实施方式可以是:

    realToFrac $ 27**(realToFrac $ 2%3) :: Rational
    
    或者您可以定义一个新的运算符:

    (*^*) :: (RealFrac a, RealFrac b) => a -> b -> a
    x *^* y = realToFrac $ realToFrac x ** realToFrac y
    
    这样你就可以写:

    27 *^* (2%3)
    
    我使用了两个
    *
    来提醒实现中使用的
    **
    ,并且我添加了一个
    ^
    来表示前两个操作符的类型。。。不确定这是否有意义,或者可能
    ^**
    ^^*
    会更好


    不过,最好只使用
    Double
    s。这实际上取决于数字代表什么以及你在用它们做什么。

    为了回答“为什么这不起作用”—哈斯克尔的多重求幂运算符实际上非常接近地反映了数学家定义求幂的方式

    • 从头算,你只知道(直接通过定义)对于自然n,表达式xn表示1·x·x·x…,n使用x。这正是
      ^
      实现的,显然它适用于任何数字类型(因为乘法总是被定义的)
    • 通过对零的“反向延拓”,将x-n定义为1/x·x·x……是有意义的…。这只适用于有乘法逆的情况,即分数。嗯,
      分数的
      ,你知道的!这就是
      ^^
      所做的
    • 要定义分数指数,可以从考虑根开始。这些基本上就是你想要的。然而,根实际上在数学上相当复杂。它们并不是独一无二的。这些根的结果类型将是表示。对于大多数用户来说,没有什么理由对这些数字进行专门处理,因此Haskell跳过了这一点。
      现在你说,好吧,但我们肯定可以定义特定数字的根。27的第三个根恰好是一个整数,但对于大多数其他数字来说,这不是真的。不明确的或部分的功能是邪恶的;因此,我们需要一个签名,比如
      numa=>a->Rational->也许a
      。但是结果通常是
      什么都没有
      ,所以老实说,这是一个非常无用的函数。如果你愿意的话,你可以自己实现它
    • 如果你直接向前走一步,它会更有用:从代数转换到微积分,数学家可以访问和对数函数,通过等式,这些函数可以覆盖所有的幂表达式
      xy =(exp(lnx))y =exp(y·lnx)。
      只要x为正†,此项功能就起作用。对于指数的定义,数学上你需要。这些存在于,即“无孔空间”。根据定义,实数是完整的,但有理数不是!手动保存原因:
      Rational
      是“无限精确的”,即每个值实际上是一个单一的精确数字。然而,在现实中,你只能使用有限数量的这种理性。
      根据设计,浮点类型并不精确,但从数学上讲,它实际上可以被很好地解释:每个
      双精度
      值代表一个完整的实数间隔,如果你取所有这些值的单位,你不仅得到一组离散点,还得到整个实数线。
      这就是为什么
      Floating
      类及其实例
      Double
      表示完全空格,以及为什么这个类有方法
      (**)::Floating a=>a->a->a


    †在中,您甚至可以定义负数的对数,尽管这会再次导致唯一性问题。

    您希望结果是什么类型?相关:@Ludwik有一个
    积分a=>分数(比率a)
    实例,Haskell中有三个幂运算符:
    (^):(Num a,Integral b)=>a->b->a
    (^^):(分数a,Integral b)=>a->b->a
    :(分数a,Integral b)=>a->b->a
    (**):(浮动a)=>a->a->a
    。因此,指数要么是
    整数
    要么是
    浮点
    ,但没有可用的
    分数
    指数。。。你应该使用
    27**(realToFrac$2%3)
    ;您希望结果是什么类型的?您想要一个
    比率吗?(2^(1/2)不合理。)是否要最接近的整数?您要双份的吗?什么类型