Euclid算法的递归实现 - 类型错误

时间:2012-06-22 15:25:25

标签: haskell functional-programming

这是代码(Euclid的GCD算法)。当然有Prelude.gcd但作为练习我正在实施自己的。

selfGCD :: Integral f => f -> f -> f  
selfGCD a b = if b == 0 then
        return a
    else 
        return (selfGCD a (mod a b))

使用 ghci ,我收到以下错误:

two.hs:32:25:  
Couldn't match type `f' with `m0 f'  
  `f' is a rigid type variable bound by  
      the type signature for selfGCD :: Integral f => f -> f -> f  
      at two.hs:31:1  
In the return type of a call of `return'  
In the expression: return a  
In the expression:  
  if b == 0 then return a else return (selfGCD a (mod a b))  

two.hs:34:25:  
Couldn't match type `f' with `m1 f'  
  `f' is a rigid type variable bound by  
      the type signature for selfGCD :: Integral f => f -> f -> f  
      at two.hs:31:1  
In the return type of a call of `return'  
In the expression: return (selfGCD a (mod a b))  
In the expression:  
  if b == 0 then return a else return (selfGCD a (mod a b))  

我该如何纠正这个问题?

2 个答案:

答案 0 :(得分:9)

删除return s。

在Haskell中,return是类型

的函数
return :: Monad m => a -> m a

而不是命令式语言中的return运算符。

因此,对于return,实现具有类型

selfGCD :: (Integral a, Monad m) => a -> a -> m a

与类型签名相反。

答案 1 :(得分:3)

首先,不要使用return。在Haskell中,它没有做你认为它做的事情。其次,你再次调用gcd的参数是交换的。它应该是selfGCD b(mod a b)

请参阅下面编辑的代码,该代码与GCD算法的预期一致。

selfGCD :: Integral f => f -> f -> f  
selfGCD a b = if b == 0 then a else selfGCD b (mod a b)