在 `floor 中输入默认值。方格`

jhu*_*jhu 3 haskell

使用-Wtype-defaults(附带-Wall),floor . sqrt . fromIntegral即使我指定了参数的类型和结果,也会给我大量警告:

?> (floor . sqrt . fromIntegral) (10 :: Int) :: Int

<interactive>:356:2-6: warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Double’
        (RealFrac a0)
          arising from a use of ‘floor’ at <interactive>:356:2-6
        (Floating a0)
          arising from a use of ‘sqrt’ at <interactive>:356:10-13
        (Num a0)
          arising from a use of ‘fromIntegral’ at <interactive>:356:17-28
    • In the first argument of ‘(.)’, namely ‘floor’
      In the expression: floor . sqrt . fromIntegral
      In the expression: (floor . sqrt . fromIntegral) (10 :: Int) :: Int

<interactive>:356:2-6: warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Double’
        (RealFrac a0)
          arising from a use of ‘floor’ at <interactive>:356:2-6
        (Floating a0)
          arising from a use of ‘sqrt’ at <interactive>:356:10-13
        (Num a0)
          arising from a use of ‘fromIntegral’ at <interactive>:356:17-28
    • In the first argument of ‘(.)’, namely ‘floor’
      In the expression: floor . sqrt . fromIntegral
      In the expression: (floor . sqrt . fromIntegral) (10 :: Int) :: Int
3
Run Code Online (Sandbox Code Playgroud)

我能够通过为 指定一个非多态类型来解决这个问题fromIntegral

?> (floor . sqrt . (fromIntegral :: Int -> Double)) (10 :: Int) :: Int
3
Run Code Online (Sandbox Code Playgroud)

以下也有效,但更麻烦:

?> (floor . sqrt . (fromIntegral :: (Integral a) => a -> Double)) (10 :: Int) :: Int
3
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 有没有更简单的方法来解决类型默认警告?(关闭-Wtype-defaults不符合条件。)
  • 这是在 Haskell 中计算这个复合函数(平方根底)的值的正确方法吗?必须使用fromIntegral并且必须指定中间类型让我想起了谚语“简单的事情很难”。

Dan*_*ner 5

有三种类型可供选择(输入类型、内部使用的中间浮点类型和结果类型),您必须以某种方式告诉编译器这三种类型。有很多组合可以修复它们,但不能少于三个。

我认为TypeApplications是一种特别方便的方式来指定这些类型。这是一种从原始注释开始的方法,它有两个注释,然后只添加一个注释以避免默认:

> :set -XTypeApplications -Wtype-defaults
> (floor . sqrt @Double . fromIntegral) (10 :: Int) :: Int
3
Run Code Online (Sandbox Code Playgroud)

这是另一个可能更符合人体工程学的(因为它对括号的确切位置更加灵活):

> (floor . sqrt . fromIntegral @Int @Double) 10 :: Int
3
Run Code Online (Sandbox Code Playgroud)

我喜欢你的第三个例子的想法,即修改你的第二个例子,这样你就不必重复Int,从而避免潜在的脆弱点。通过使用特殊_类型应用程序,您可以通过类型应用程序以稍微不那么麻烦的方式实现这一点,它允许编译器对类型变量之一使用通常的推理过程:

> (floor . sqrt . fromIntegral @_ @Double) (10 :: Int) :: Int
3
Run Code Online (Sandbox Code Playgroud)


dup*_*ode 5

这是在 Haskell 中计算这个复合函数(平方根下限)值的正确方法吗?必须使用fromIntegral并必须指定中间类型让我想起了谚语“简单的事情是困难的”。

您最终要计算整数平方根,因此理想情况下您希望避免通过 进行计算sqrt :: Floating a => a -> a。你可能会。例如,使用arithmoiintegerSquareRoot :: Integral a => a -> a库中的内容。

至于你的第一个问题,我赞同Daniel Wagner关于使用TypeApplications扩展来指定中间类型的建议。