time :: Int -> (Int,Int,Int)
time x = ((x/3600),(x`mod`3600)/60,((x`mod`3600)`mod`60))
定义时间所需的分数Int实例
expample =
时间x =(小时,分钟,秒)
时间3600 =(1,0,0)
给出一个秒的时间,必须在示例中显示它(小时,分钟,秒)3600是1h 0m 0s
答案 0 :(得分:5)
我相信您收到该错误是因为您使用带有/
参数的Int
运算符。您可以使用div
来消除错误,如下所示:
time :: Int -> (Int,Int,Int)
time x = ((x `div` 3600),(x `mod` 3600) `div` 60,((x `mod` 3600) `mod` 60))
正如其他人所指出的那样,(/)
要求参数为Fractional
,而div
则对Integral
值感到满意。
答案 1 :(得分:4)
您不能对整数使用常规除法运算符。在数学和Haskell中都是如此,因为除数仅在数学结构为Field时才有效。整数没有定义除法,但你可以执行类似的名为整数除法(是的,误导性的名称)或截断的除法。这是在Haskell中使用div
函数实现的,您可以将其用作:
time :: Int -> (Int, Int, Int)
time x = (x `div` 3600, (x `mod` 3600) `div` 60, (x `mod` 3600) `mod` 60)
此处,我只是简单地将/
的每个实例替换为其中缀形式的div
,否则不会更改您的算法。
那么实现/
运算符的类型意味着什么?如果我们加载GHCi:
> :info (/)
class Num a => Fractional a where
(/) :: a -> a -> a
...
-- Defined in 'GHC.Real'
infixl 7 /
这告诉我们/
是Fractional
类型类的成员,实现它的任何东西也必须实现Num
类型类。简而言之,可以分割的东西必须是分数。 Fractional
类型类中还有什么?
> :info Fractional
class Num a => Fractional a where
(/) :: a -> a -> a
recip :: a -> a
fromRational :: Rational -> a
instance Fractional Float
instance Fractional Double
因此,Fractional
数字具有除法,倒数运算和Rational
数字的转换。理想情况下,a * recip a == a / a == 1
,因为我们熟悉的分数集(理性,实数,复数)都是如此。
答案 2 :(得分:3)
它向您显示错误的原因是(/)
具有以下类型:
λ> :t (/)
(/) :: Fractional a => a -> a -> a
因此,它只接受并返回小数字,例如Float和Double。解决此问题的一种方法是使用div
函数,其类型为div :: Integral a => a -> a -> a
。
time x = ((x `div` 3600),(x`mod`3600) `div` 60,((x`mod`3600)`mod`60))
解决此问题的另一种方法是对将应用于fromIntegral
函数的数字使用/
函数,并在返回时执行正确的类型转换:
time :: Int -> (Int, Int, Int)
time x = (a,b,c)
where a = ci $ fi x / fi 3600
b = ci $ fi (x `mod` 3600) / fi 60
c = (x `mod` 3600) `mod` 60
fi = fromIntegral
ci = ceiling