Reputation: 81
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
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