Haskell中兼顾简洁代码与消除类型默认警告的方法
解决Haskell中
-Wall警告与代码简洁性的平衡问题 嘿,作为Haskell新手碰到这种“鱼和熊掌”的问题太正常了!我之前也纠结过怎么既保持$和.的简洁写法,又消除那个恼人的默认类型警告,刚好有几个靠谱的办法分享给你:
方法1:给sqrt显式指定类型签名(函数组合风格)
你可以直接给sqrt限定类型,这样编译器就不用默认推导了,而且完全用.来组合函数,没有多余括号:
module Helpers (intSqrt1, intSqrt2) where intSqrt1 :: Int -> Int intSqrt1 = truncate . (sqrt :: Integral a => a -> Double) . fromIntegral intSqrt2 :: Int -> Int intSqrt2 x = truncate ( sqrt (fromIntegral x) :: Double)
这里给sqrt加上了Integral a => a -> Double的类型,明确告诉它接收Integral类型的输入(fromIntegral x刚好符合),返回Double,完美避免了默认类型推导的警告,同时保持了函数式的简洁写法。
方法2:用asTypeOf约束类型($链式风格)
如果你更喜欢用$的链式写法,asTypeOf函数可以帮你在不增加括号的情况下指定类型:
module Helpers (intSqrt1, intSqrt2) where intSqrt1 :: Int -> Int intSqrt1 x = truncate $ sqrt $ fromIntegral x `asTypeOf` (0 :: Double) intSqrt2 :: Int -> Int intSqrt2 x = truncate ( sqrt (fromIntegral x) :: Double)
asTypeOf的作用是让左边的表达式和右边的表达式类型一致,这里就是告诉编译器sqrt的结果类型是Double,和0 :: Double一样,既保持了$的链式简洁,又消除了警告。
为什么会出现这个警告?
简单说,sqrt的类型是Floating a => a -> a,而fromIntegral x的类型是Num b => b——编译器需要从所有Floating类型里选一个默认的(这里默认是Double),但-Wall会把这种“隐式默认推导”当成警告提出来。我们上面的两种方法都是显式告诉编译器我们要的类型,所以警告就消失了。
内容的提问来源于stack exchange,提问作者Penguino
相关产品推荐
相关产品推荐

