Haskell 无法将预期类型“a”与实际类型“Integer”匹配`

Haskell 无法将预期类型“a”与实际类型“Integer”匹配`,haskell,types,Haskell,Types,我有一个treeBuild函数没有编译,因为where子句中的签名: unfold :: (a -> Maybe (a,b,a)) -> a -> BinaryTree b unfold f x = case f x of Nothing -> Leaf Just (s,t,u) -> Node (unfold f s) t (unfold f u) treeBuild :: Integer -> Binar

我有一个treeBuild函数没有编译,因为where子句中的签名:

unfold :: (a -> Maybe (a,b,a)) -> a -> BinaryTree b
unfold f x = case f x of Nothing -> Leaf
                         Just (s,t,u) -> Node (unfold f s) t (unfold f u)

treeBuild :: Integer -> BinaryTree Integer
treeBuild n = unfold f 0
    where f :: a -> Maybe (a,b,a)
          f x
              | x == n = Nothing
              | otherwise = Just (x+1, x, x+1)        
我发现了以下编译器错误:

* Couldn't match expected type `a' with actual type `Integer'
  `a' is a rigid type variable bound by
    the type signature for:
      f :: forall a b. a -> Maybe (a, b, a)
    at D:\haskell\chapter12\src\Small.hs:85:16
* In the second argument of `(==)', namely `n'
  In the expression: x == n
  In a stmt of a pattern guard for
                 an equation for `f':
    x == n
* Relevant bindings include
    x :: a (bound at D:\haskell\chapter12\src\Small.hs:86:13)
    f :: a -> Maybe (a, b, a)
      (bound at D:\haskell\chapter12\src\Small.hs:86:11)
f的签名有什么问题?

错误 在您的程序中,您可以编写:

treeBuild :: Integer -> BinaryTree Integer
treeBuild n = unfold f 0
    where f :: a -> Maybe (a,b,a)
          f x
              | x == n = Nothing
              | otherwise = Just (x+1, x, x+1)
在这里,我们简单地把f变成一个函数f::Integer->可能是Integer,Integer,Integer

泛化treeBuild函数 我们可以——这是更推荐的——概括treeBuild函数并稍微专门化f函数:

treeBuild :: (Num a, Eq a) => a -> BinaryTree a
treeBuild n = unfold f 0
    where f x
              | x == n = Nothing
              | otherwise = Just (x+1, x, x+1)
然后f将具有类型f::Num a,Eq a=>a->a,a,a

现在,我们可以为任何数字类型和支持相等的类型构建树。

错误 在您的程序中,您可以编写:

treeBuild :: Integer -> BinaryTree Integer
treeBuild n = unfold f 0
    where f :: a -> Maybe (a,b,a)
          f x
              | x == n = Nothing
              | otherwise = Just (x+1, x, x+1)
在这里,我们简单地把f变成一个函数f::Integer->可能是Integer,Integer,Integer

泛化treeBuild函数 我们可以——这是更推荐的——概括treeBuild函数并稍微专门化f函数:

treeBuild :: (Num a, Eq a) => a -> BinaryTree a
treeBuild n = unfold f 0
    where f x
              | x == n = Nothing
              | otherwise = Just (x+1, x, x+1)
然后f将具有类型f::Num a,Eq a=>a->a,a,a


现在,我们可以为任何数字类型和支持相等的类型构建树。

如果不是整数或至少有一些已知约束,您如何比较x::a和n::Integer?或者代替这个反问句:==属于类型a->a->Bool,所以如果其中一个是整数,那么两个都应该是整数。如果没有一个是整数或者至少有一些已知的约束条件,你怎么能比较x::a和n::integer呢?或者代替反问句:==是类型a->a->Bool,所以如果其中一个是整数,那么两个都应该是整数。在我的示例中,变量a没有类型,因为它不能正常工作?我没有澄清a的类型。a不是一个变量,它是一个类型变量。您不必为了定义函数而澄清函数的类型。Haskell可以在调用函数本身时派生具体类型。好的,是的,对不起。因此类型变量a还没有分配给类型,这是因为它工作不正常?@zero\u编码:您指定了一个f,但在treeBuild的范围内。这意味着您指定了一个自由a,可以说,这与展开调用冲突。您能给我展示另一个自由a的示例吗?在我的例子中,变量a没有类型,这是因为它不能正常工作?我没有澄清a的类型。a不是一个变量,它是一个类型变量。您不必为了定义函数而澄清函数的类型。Haskell可以在调用函数本身时派生具体类型。好的,是的,对不起。因此类型变量a还没有分配给类型,这是因为它工作不正常?@zero\u编码:您指定了一个f,但在treeBuild的范围内。这意味着您指定了一个自由a,可以说,这与展开调用冲突。您能给我展示另一个自由a的示例吗?或者,你说的“免费”是什么意思?