Ben Borg
Ben Borg

Reputation: 81

Expected type not matching Actual Type

Let's say for sake of argument that I have the two functions defined below, along with the Var type:

  data Var = String | Int

   Increment :: Int -> Int 
   Increment a = (a +1)

   Compute :: Var -> Maybe Int
    Compute b = case b of 
         Int -> Just(Increment b)
         String -> Nothing

Even though I'm checking that b is of type Int before calling increment on it, I'm getting an error stating that the Expected type Int is not matched by the Actual type Var.

Is there a way around this?

Upvotes: 0

Views: 323

Answers (1)

jpmarinier
jpmarinier

Reputation: 4733

One of the problems is that the definition:

data Var = String | Int

gets parsed by Haskell exactly like:

data Language = English | Spanish | French | Russian

because the two constructors have no arguments. So Var is essentially an enumerative type, with just 2 possible values named String and Int which happen to hide their namesake Haskell built-in data types..

Testing under the ghci interpreter:

 λ> 
 λ> data Var = String | Int deriving (Eq, Show)
 λ> 
 λ> v = String
 λ> 
 λ> :type v
 v :: Var
 λ> 
 λ> v
 String
 λ> 

You probably wanted something like:

data Var = MyVarString String | MyVarInt Int  deriving  (Eq, Show)

where String is the built-in data type, and MyVarString is your own private local constructor.

 λ> 
 λ> data Var = MyVarString String | MyVarInt Int  deriving  (Eq, Show)
 λ> 
 λ> v = MyVarString "abc"
 λ> 
 λ> v
 MyVarString "abc"
 λ> 
 λ> :type v
 v :: Var
 λ> 

Also, your local functions need to be slightly reformatted:

-- leftmost-indented, name starting with lowercase letter:
increment :: Int -> Int 
increment a = (a +1)

-- leftmost-indented, name starting with lowercase letter:
compute :: Var -> Maybe Int
compute b = case b of 
         MyVarInt v      ->  Just (increment v)
         MyVarString st  ->  Nothing

Sample test program:

main :: IO ()
main = do
    putStrLn "Hello impure world !"
    let  v1 = MyVarInt 42
         mi = compute v1
    putStrLn ("compute v1 : " ++ (show mi))

Test program output:

Hello impure world !
compute v1 : Just 43

Upvotes: 2

Related Questions