1

I want to create an expression that can be composed of variables or constants (such as mathematical expressions) so I created a newtype to represent those expressions as strings, but when using it on functions it does not work:

newtype Expr = Expr String deriving (Show)
constant :: Int -> Expr
constant n = show n

variable :: String -> Expr
variable v = v

the error I get is that the type Expr does not match with String, and I cant use the function show even though I defined it earlier. please help!

2 Answers 2

5

You have a newtype wrapper, but you're trying to use it as if it were a type synonym. You can either go all the way with type, by changing your first line to type Expr = String, or go all the way with newtype, by putting Expr $ right after the = in the definitions of constant and variable.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you so much that indeed helped solve the problem! If it wasnt too much of a bother, I'd like to asker further, Is it possible to not specify the constructor's type as String, but rather as "a" (for example) so that it could be more abstract and take different types of values (such as a string or an int)?
@GuilhermeSalgueiro You probably want something like newtype Expr = ConstantExpr Int | VariableExpr String deriving (Show).
1

As pointed out in the other answer you are treating the newtype as a type synonym. Remember that newtype is now creating a wrapper around your String, so you need to use its type constructor ExprConstructor to instantiate it.

newtype Expr = ExprConstructor String deriving (Show)

constant :: Int -> Expr
constant = ExprConstructor . show 

variable :: String -> Expr
variable = ExprConstructor

3 Comments

thank you so much for taking your time to help me! If it wasnt too much of a bother, I'd like to asker further, Is it possible to not specify the constructor's type as String, but rather as "a" (for example) so that it could be more abstract and take different types of values (such as a string or an int)?
If you want to generalise your expression you can introduce your type variable on the left hand side newtype Expr a = ExprConstructor a. But now you cannot derive Show as easy anymore. In this case you probably want to write your instance by hand like instance Show a => Show (Expr a) where ; show (ExprConstructor a) = show a
Parameterizing the type doesn't prevent you from deriving Show.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.