Unfortunately I have been facing a strange error. It happens while using infix with data constructor.
I am new to Haskell. Can any one help me in this regard ?
Prelude> data L a = Cons a (L a) | Emp deriving Show
Prelude> 10 `Cons` Emp
Cons 10 Emp
Prelude> 10 `Cons` 10 `Cons` Emp
<interactive>:43:1: error:
• Non type-variable argument in the constraint: Num (L a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a. (Num a, Num (L a)) => L (L a)
Prelude> 10 `Cons` (10 `Cons` Emp)
Cons 10 (Cons 10 Emp)
Prelude> 10 `Cons` 10 `Cons` Emp
<interactive>:45:1: error:
• Non type-variable argument in the constraint: Num (L a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a. (Num a, Num (L a)) => L (L a)
Prelude> data L a = Emp | Cons a (L a) deriving Show
Prelude> 10 `Cons` 10 `Cons` Emp
<interactive>:47:1: error:
• Non type-variable argument in the constraint: Num (L a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a. (Num a, Num (L a)) => L (L a)
Prelude>
CodePudding user response:
You can define the data constructor to be right-associative,
infixr 5 `Cons`
data L a = Cons a (L a) | Emp deriving Show
Then it will work as you expected.
main = print $ (21::Int) `Cons` 42 `Cons` Emp
-- => Cons 21 (Cons 42 Emp)
CodePudding user response:
What you are trying to do is to write the following Cons 10 (Cons 10 Emp)
with infix operators.
When you make an ordinary function infix using backticks, (`), the infix operator is left associative. This means that:
λ> 10 `Cons` 10 `Cons` Emp
will be parenthesized as follows:
λ> ((10 `Cons` 10) `Cons` Emp)
While you want it to be:
λ> 10 `Cons` ( 10 `Cons` Emp)
Because that's equal Cons 10 (Cons 10 Emp)
.
This is of course right associative, therefore you need to explicitly parenthesize it.
Markus Mayr linked the QA that refers to the Haskell Report.