简体   繁体   中英

Couldn't match expected type `a` with actual type `Integer`

I have a treeBuild function does not get compiled, because the signature in the where clause:

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)        

and I've got following compiler error:

* 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)

What is wrong with signature of f ?

The error

In your program you write:

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

So that means that you want to check the equality between an Integer and an a . But (==) has type signature: (==) :: Eq a => a -> a -> Bool . So that means in Haskell the two operands should have the same type .

You thus have two options: (1) you specify the f function, or (2) you generalize the treeBuild function.

Specialize the f function

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

Here we simply make f a function f :: Integer -> Maybe (Integer,Integer,Integer) .

Generalize the treeBuild function

We can - and this is more recommended - generalize the treeBuild function (and slightly specialize the f function):

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

Then f will have the type f :: -> Maybe ( ) . -> Maybe ( ) 。

Since now we can build trees for any type that is a numerical type and supports equality.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM