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.
