我是Haskell的新手,我不明白为什么我的警卫不会接受它。这是我的代码。如果b
是a
的分隔符,则应该触发警卫。
gCF :: Integer -> Integer -> Integer;
gCF n p
| (p <= 0 || n <= 0) = error "Input should be positive"
| (p > n) = f p n
| otherwise = f n p
where
f :: Integer -> Integer -> Integer;
f a b
| (fromInteger (a `div` b) / 1 == a / b) = b
| otherwise = f a (b - 1)
这是显示的错误。
testscript.hs:168:28: error:
• No instance for (Fractional Integer) arising from a use of ‘/’
• In the first argument of ‘(==)’, namely
‘fromInteger (a `div` b) / 1’
In the expression: (fromInteger (a `div` b) / 1 == a / b)
In a stmt of a pattern guard for
an equation for ‘f’:
(fromInteger (a `div` b) / 1 == a / b)
|
168 | | (fromInteger (a `div` b) / 1 == a / b) = b | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
答案 0 :(得分:4)
我认为你让它变得更复杂,必要。在Int
eger和Float
世界之间转换数字可能很危险,因为它会引入舍入问题。
如果我理解正确,您想要a
检查b
是否可分割。您可以通过验证mod a b == 0
来检查这一点,我们仍处于整数世界中。所以我们可以将程序重写为:
gCF :: Integer -> Integer -> Integer
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| p > n = f p n
| otherwise = f n p
where f a b | mod a b == 0 = b
| otherwise = f a (b-1)
由于a
在递归调用中没有变化,我们可以将其分解为:
gCF :: Integer -> Integer -> Integer
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| otherwise = f (min p n)
where a = max p n
f b | mod a b == 0 = b
| otherwise = f (b-1)
我们还可以对签名进行概括,使其适用于任何Integral
类型:
gCF :: Integral i => i -> i -> i
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| otherwise = f (min p n)
where a = max p n
f b | mod a b == 0 = b
| otherwise = f (b-1)
答案 1 :(得分:0)
我找到了解决方案!
gCF :: Integer -> Integer -> Integer;
gCF n p
| (p <= 0 || n <= 0) = error "Input should be positive"
| (p > n) = floor (f (fromInteger p) (fromInteger n) (fromInteger n))
| otherwise = floor (f (fromInteger n) (fromInteger p) (fromInteger p))
where
f :: Float -> Float -> Float -> Float;
f a b c
| (fromInteger (floor (a / c)) == a / c) && (fromInteger (floor (b / c)) == b / c) = c
| otherwise = f a b (c - 1)