使用-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不符合条件。)fromIntegral并且必须指定中间类型让我想起了谚语“简单的事情很难”。有三种类型可供选择(输入类型、内部使用的中间浮点类型和结果类型),您必须以某种方式告诉编译器这三种类型。有很多组合可以修复它们,但不能少于三个。
我认为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)
这是在 Haskell 中计算这个复合函数(平方根下限)值的正确方法吗?必须使用
fromIntegral并必须指定中间类型让我想起了谚语“简单的事情是困难的”。
您最终要计算整数平方根,因此理想情况下您希望避免通过 进行计算sqrt :: Floating a => a -> a。你可能会。例如,使用arithmoiintegerSquareRoot :: Integral a => a -> a库中的内容。
至于你的第一个问题,我赞同Daniel Wagner关于使用TypeApplications扩展来指定中间类型的建议。
| 归档时间: |
|
| 查看次数: |
203 次 |
| 最近记录: |