无法将预期类型“a”与实际类型“整数”匹配

时间:2017-06-21 13:43:56

标签: 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 -> 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的签名有什么问题?

1 个答案:

答案 0 :(得分:8)

错误

在你的课程中你写道:

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)

这意味着您要检查Integera之间的相等性。但(==)具有类型签名:(==) :: Eq a => a -> a -> Bool。所以这意味着在Haskell中两个操作数应该具有相同的类型

因此,您有两个选择:(1)指定f函数,或(2)概括treeBuild函数。

专门化f函数

treeBuild :: Integer -> BinaryTree Integer
treeBuild n = unfold f 0
    where f :: Integer -> Maybe (Integer,Integer,Integer)
          f x
              | x == n = Nothing
              | otherwise = Just (x+1, x, x+1)

我们只需将f设为函数f :: Integer -> Maybe (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 -> Maybe (a,a,a)类型。

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