使用-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
我能够通过为fromIntegral
指定一种非多态类型来解决这个问题。
λ> (floor . sqrt . (fromIntegral :: Int -> Double)) (10 :: Int) :: Int
3
以下内容也有效,但更麻烦:
λ> (floor . sqrt . (fromIntegral :: (Integral a) => a -> Double)) (10 :: Int) :: Int
3
我的问题是:
-Wtype-defaults
不符合条件。)fromIntegral
并指定中间类型,这让我想起了一句谚语:“简单的事情是困难的。”发布于 2018-09-27 13:19:38
有三种类型可供选择(输入类型、内部使用的中间浮点类型和结果类型),您必须以某种方式告诉编译器这三种类型。有很多组合来修复它们,但你不能短于三。
我认为TypeApplications
是一种特别方便的方法来指定这些类型。这里有一种方法可以从原来的注释(其中有两个注释)开始,然后只添加一个来避免默认情况:
> :set -XTypeApplications -Wtype-defaults
> (floor . sqrt @Double . fromIntegral) (10 :: Int) :: Int
3
这里还有一个可能更符合人体工程学的方法(因为它对于括号的确切位置更灵活):
> (floor . sqrt . fromIntegral @Int @Double) 10 :: Int
3
我喜欢第三个示例的想法,即修改第二个示例,使您不必重复Int
,从而避免潜在的脆弱点。通过使用特殊的_
类型应用程序,您可以以稍微简单一些的方式实现这一点,它允许编译器对其中一个类型变量使用通常的推理过程:
> (floor . sqrt . fromIntegral @_ @Double) (10 :: Int) :: Int
3
发布于 2018-09-27 13:26:58
这是计算Haskell中这个复合函数(平方根层)值的正确方法吗?必须使用
fromIntegral
并指定中间类型,这让我想起了一句谚语:“简单的事情是困难的。”
您最终是在计算整数平方根,因此理想情况下,您希望避免通过sqrt :: Floating a => a -> a
路由计算。你可能会。例如,使用算术库中的integerSquareRoot :: Integral a => a -> a
。
至于您的第一个问题,我第二个Daniel Wagner's suggestion使用TypeApplications
扩展来指定中间类型。
https://stackoverflow.com/questions/52537287
复制相似问题