happy fails to generate valid Haskell when `<$>` is used.
The bug in question came from a parser hosted here. In short, if you write
| FunName Universals OptTermetric OptType OptExpression { PreF $1 (fst <$> $4) [] $2 [NoArgs] (snd <$> $4) $3 $5 }
instead of
| FunName Universals OptTermetric OptType OptExpression { PreF $1 (fmap fst $4) [] $2 [NoArgs] (fmap snd $4) $3 $5 }
it will fail during compilation with an arcane error message, viz.
/home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4832:38: error:
• Couldn't match type ‘Maybe (String, Type AlexPosn)
-> (b0, b0) -> b0’
with ‘Maybe (Expression AlexPosn)’
Expected type: HappyStk
(HappyAbsSyn
(ATS AlexPosn)
[Declaration AlexPosn]
[Type AlexPosn]
[Type AlexPosn]
(Type AlexPosn)
[Arg AlexPosn]
[Arg AlexPosn]
(Arg AlexPosn)
(Arg AlexPosn)
(Expression AlexPosn)
[Pattern AlexPosn]
(Pattern AlexPosn)
[(Pattern AlexPosn, LambdaType AlexPosn, Expression AlexPosn)]
[(Expression AlexPosn, LambdaType AlexPosn, Expression AlexPosn)]
(Maybe [Expression AlexPosn], [Expression AlexPosn])
[Expression AlexPosn]
[Expression AlexPosn]
(LambdaType AlexPosn)
(LambdaType AlexPosn)
(Expression AlexPosn)
[Type AlexPosn]
(Expression AlexPosn)
[StaticExpression AlexPosn]
[Declaration AlexPosn]
(StaticExpression AlexPosn)
(Expression AlexPosn)
(AlexPosn, StaticExpression AlexPosn)
(Sort AlexPosn)
[String]
(Existential AlexPosn)
[StaticExpression AlexPosn]
(Universal AlexPosn)
[[Type AlexPosn]]
[[Type AlexPosn]]
(Either (StaticExpression AlexPosn) (Expression AlexPosn))
(Implementation AlexPosn)
(Implementation AlexPosn)
(Name AlexPosn)
(Name AlexPosn)
[(String, Expression AlexPosn)]
[(String, Type AlexPosn)]
[String]
(Maybe (Type AlexPosn))
[StaticExpression AlexPosn]
(Leaf AlexPosn)
[Leaf AlexPosn]
[Universal AlexPosn]
(Maybe (StaticExpression AlexPosn))
(UnOp AlexPosn)
(BinOp AlexPosn)
(Maybe (Expression AlexPosn))
(DataPropLeaf AlexPosn)
[DataPropLeaf AlexPosn]
String
(Maybe (String, Type AlexPosn))
(PreFunction AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn)
[Declaration AlexPosn]
String
(Maybe (Type AlexPosn))
[Arg AlexPosn]
[SortArg AlexPosn]
(Maybe [SortArg AlexPosn])
(Declaration AlexPosn)
(Fixity AlexPosn)
String
[String]
(StackFunction AlexPosn)
[Declaration AlexPosn]
(Declaration AlexPosn)
(DataSortLeaf AlexPosn)
[DataSortLeaf AlexPosn]
(Declaration AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn))
-> HappyStk
(HappyAbsSyn
(ATS AlexPosn)
[Declaration AlexPosn]
[Type AlexPosn]
[Type AlexPosn]
(Type AlexPosn)
[Arg AlexPosn]
[Arg AlexPosn]
(Arg AlexPosn)
(Arg AlexPosn)
(Expression AlexPosn)
[Pattern AlexPosn]
(Pattern AlexPosn)
[(Pattern AlexPosn, LambdaType AlexPosn, Expression AlexPosn)]
[(Expression AlexPosn, LambdaType AlexPosn, Expression AlexPosn)]
(Maybe [Expression AlexPosn], [Expression AlexPosn])
[Expression AlexPosn]
[Expression AlexPosn]
(LambdaType AlexPosn)
(LambdaType AlexPosn)
(Expression AlexPosn)
[Type AlexPosn]
(Expression AlexPosn)
[StaticExpression AlexPosn]
[Declaration AlexPosn]
(StaticExpression AlexPosn)
(Expression AlexPosn)
(AlexPosn, StaticExpression AlexPosn)
(Sort AlexPosn)
[String]
(Existential AlexPosn)
[StaticExpression AlexPosn]
(Universal AlexPosn)
[[Type AlexPosn]]
[[Type AlexPosn]]
(Either (StaticExpression AlexPosn) (Expression AlexPosn))
(Implementation AlexPosn)
(Implementation AlexPosn)
(Name AlexPosn)
(Name AlexPosn)
[(String, Expression AlexPosn)]
[(String, Type AlexPosn)]
[String]
(Maybe (Type AlexPosn))
[StaticExpression AlexPosn]
(Leaf AlexPosn)
[Leaf AlexPosn]
[Universal AlexPosn]
(Maybe (StaticExpression AlexPosn))
(UnOp AlexPosn)
(BinOp AlexPosn)
(Maybe (Expression AlexPosn))
(DataPropLeaf AlexPosn)
[DataPropLeaf AlexPosn]
String
(Maybe (String, Type AlexPosn))
(PreFunction AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn)
[Declaration AlexPosn]
String
(Maybe (Type AlexPosn))
[Arg AlexPosn]
[SortArg AlexPosn]
(Maybe [SortArg AlexPosn])
(Declaration AlexPosn)
(Fixity AlexPosn)
String
[String]
(StackFunction AlexPosn)
[Declaration AlexPosn]
(Declaration AlexPosn)
(DataSortLeaf AlexPosn)
[DataSortLeaf AlexPosn]
(Declaration AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn))
Actual type: HappyStk
(HappyAbsSyn
(ATS AlexPosn)
[Declaration AlexPosn]
[Type AlexPosn]
[Type AlexPosn]
(Type AlexPosn)
[Arg AlexPosn]
[Arg AlexPosn]
(Arg AlexPosn)
(Arg AlexPosn)
(Expression AlexPosn)
[Pattern AlexPosn]
(Pattern AlexPosn)
[(Pattern AlexPosn, LambdaType AlexPosn, Expression AlexPosn)]
[(Expression AlexPosn, LambdaType AlexPosn, Expression AlexPosn)]
(Maybe [Expression AlexPosn], [Expression AlexPosn])
[Expression AlexPosn]
[Expression AlexPosn]
(LambdaType AlexPosn)
(LambdaType AlexPosn)
(Expression AlexPosn)
[Type AlexPosn]
(Expression AlexPosn)
[StaticExpression AlexPosn]
[Declaration AlexPosn]
(StaticExpression AlexPosn)
(Expression AlexPosn)
(AlexPosn, StaticExpression AlexPosn)
(Sort AlexPosn)
[String]
(Existential AlexPosn)
[StaticExpression AlexPosn]
(Universal AlexPosn)
[[Type AlexPosn]]
[[Type AlexPosn]]
(Either (StaticExpression AlexPosn) (Expression AlexPosn))
(Implementation AlexPosn)
(Implementation AlexPosn)
(Name AlexPosn)
(Name AlexPosn)
[(String, Expression AlexPosn)]
[(String, Type AlexPosn)]
[String]
(Maybe (Type AlexPosn))
[StaticExpression AlexPosn]
(Leaf AlexPosn)
[Leaf AlexPosn]
[Universal AlexPosn]
(Maybe (StaticExpression AlexPosn))
(UnOp AlexPosn)
(BinOp AlexPosn)
(Maybe (String, Type AlexPosn) -> (b0, b0) -> b0)
(DataPropLeaf AlexPosn)
[DataPropLeaf AlexPosn]
String
(Maybe (String, Type AlexPosn))
(PreFunction AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn)
[Declaration AlexPosn]
String
(Maybe (Type AlexPosn))
[Arg AlexPosn]
[SortArg AlexPosn]
(Maybe [SortArg AlexPosn])
(Declaration AlexPosn)
(Fixity AlexPosn)
String
[String]
(StackFunction AlexPosn)
[Declaration AlexPosn]
(Declaration AlexPosn)
(DataSortLeaf AlexPosn)
[DataSortLeaf AlexPosn]
(Declaration AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn))
-> HappyStk
(HappyAbsSyn
(ATS AlexPosn)
[Declaration AlexPosn]
[Type AlexPosn]
[Type AlexPosn]
(Type AlexPosn)
[Arg AlexPosn]
[Arg AlexPosn]
(Arg AlexPosn)
(Arg AlexPosn)
(Expression AlexPosn)
[Pattern AlexPosn]
(Pattern AlexPosn)
[(Pattern AlexPosn, LambdaType AlexPosn, Expression AlexPosn)]
[(Expression AlexPosn, LambdaType AlexPosn, Expression AlexPosn)]
(Maybe [Expression AlexPosn], [Expression AlexPosn])
[Expression AlexPosn]
[Expression AlexPosn]
(LambdaType AlexPosn)
(LambdaType AlexPosn)
(Expression AlexPosn)
[Type AlexPosn]
(Expression AlexPosn)
[StaticExpression AlexPosn]
[Declaration AlexPosn]
(StaticExpression AlexPosn)
(Expression AlexPosn)
(AlexPosn, StaticExpression AlexPosn)
(Sort AlexPosn)
[String]
(Existential AlexPosn)
[StaticExpression AlexPosn]
(Universal AlexPosn)
[[Type AlexPosn]]
[[Type AlexPosn]]
(Either (StaticExpression AlexPosn) (Expression AlexPosn))
(Implementation AlexPosn)
(Implementation AlexPosn)
(Name AlexPosn)
(Name AlexPosn)
[(String, Expression AlexPosn)]
[(String, Type AlexPosn)]
[String]
(Maybe (Type AlexPosn))
[StaticExpression AlexPosn]
(Leaf AlexPosn)
[Leaf AlexPosn]
[Universal AlexPosn]
(Maybe (StaticExpression AlexPosn))
(UnOp AlexPosn)
(BinOp AlexPosn)
(Maybe (String, Type AlexPosn) -> (b0, b0) -> b0)
(DataPropLeaf AlexPosn)
[DataPropLeaf AlexPosn]
String
(Maybe (String, Type AlexPosn))
(PreFunction AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn)
[Declaration AlexPosn]
String
(Maybe (Type AlexPosn))
[Arg AlexPosn]
[SortArg AlexPosn]
(Maybe [SortArg AlexPosn])
(Declaration AlexPosn)
(Fixity AlexPosn)
String
[String]
(StackFunction AlexPosn)
[Declaration AlexPosn]
(Declaration AlexPosn)
(DataSortLeaf AlexPosn)
[DataSortLeaf AlexPosn]
(Declaration AlexPosn)
(Declaration AlexPosn)
(Declaration AlexPosn))
• In the third argument of ‘happyReduce’, namely
‘happyReduction_340’
In the expression: happyReduce 6# 55# happyReduction_340
In an equation for ‘happyReduce_340’:
happyReduce_340 = happyReduce 6# 55# happyReduction_340
|
4832 | happyReduce_340 = happyReduce 6# 55# happyReduction_340
| ^^^^^^^^^^^^^^^^^^
/home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4845:38: error:
• Couldn't match expected type ‘Maybe String’
with actual type ‘Bool’
• In the second argument of ‘PreF’, namely
‘(fst < happy_var_6 happy_var_5)’
In the first argument of ‘happyIn59’, namely
‘((PreF
happy_var_1
(fst < happy_var_6 happy_var_5)
[]
[]
happy_var_3
(snd < happy_var_6 happy_var_5)
Nothing
happy_var_6))’
In the first argument of ‘HappyStk’, namely
‘happyIn59
((PreF
happy_var_1
(fst < happy_var_6 happy_var_5)
[]
[]
happy_var_3
(snd < happy_var_6 happy_var_5)
Nothing
happy_var_6))’
|
4845 | ((PreF happy_var_1 (fst <happy_var_6 happy_var_5) [] [] happy_var_3 (snd <happy_var_6 happy_var_5) Nothing happy_var_6)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4845:87: error:
• Couldn't match expected type ‘Maybe (Type a)’
with actual type ‘Bool’
• In the sixth argument of ‘PreF’, namely
‘(snd < happy_var_6 happy_var_5)’
In the first argument of ‘happyIn59’, namely
‘((PreF
happy_var_1
(fst < happy_var_6 happy_var_5)
[]
[]
happy_var_3
(snd < happy_var_6 happy_var_5)
Nothing
happy_var_6))’
In the first argument of ‘HappyStk’, namely
‘happyIn59
((PreF
happy_var_1
(fst < happy_var_6 happy_var_5)
[]
[]
happy_var_3
(snd < happy_var_6 happy_var_5)
Nothing
happy_var_6))’
• Relevant bindings include
happy_var_3 :: [Arg a]
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4841:39)
happy_var_1 :: Name a
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4840:43)
happyRest :: HappyStk
(HappyAbsSyn
t4
t5
t6
t7
t8
[Arg a]
t10
t11
t12
t13
t14
t15
t16
t17
t18
t19
t20
t21
t22
t23
t24
t25
t26
t27
t28
t29
t30
t31
t32
t33
t34
t35
t36
t37
t38
t39
t40
(Name a)
t42
t43
t44
t45
t46
t47
t48
t49
t50
t51
t52
t53
(t58 -> (b, b) -> b)
t55
t56
t57
t58
(PreFunction a)
t60
t61
t62
t63
t64
t65
t66
t67
t68
t69
t70
t71
t72
t73
t74
t75
t76
t77
t78
t79
t80)
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4839:9)
happy_x_1 :: HappyAbsSyn
t4
t5
t6
t7
t8
[Arg a]
t10
t11
t12
t13
t14
t15
t16
t17
t18
t19
t20
t21
t22
t23
t24
t25
t26
t27
t28
t29
t30
t31
t32
t33
t34
t35
t36
t37
t38
t39
t40
(Name a)
t42
t43
t44
t45
t46
t47
t48
t49
t50
t51
t52
t53
(t58 -> (b, b) -> b)
t55
t56
t57
t58
(PreFunction a)
t60
t61
t62
t63
t64
t65
t66
t67
t68
t69
t70
t71
t72
t73
t74
t75
t76
t77
t78
t79
t80
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4838:9)
happy_x_2 :: HappyAbsSyn
t4
t5
t6
t7
t8
[Arg a]
t10
t11
t12
t13
t14
t15
t16
t17
t18
t19
t20
t21
t22
t23
t24
t25
t26
t27
t28
t29
t30
t31
t32
t33
t34
t35
t36
t37
t38
t39
t40
(Name a)
t42
t43
t44
t45
t46
t47
t48
t49
t50
t51
t52
t53
(t58 -> (b, b) -> b)
t55
t56
t57
t58
(PreFunction a)
t60
t61
t62
t63
t64
t65
t66
t67
t68
t69
t70
t71
t72
t73
t74
t75
t76
t77
t78
t79
t80
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4837:9)
happy_x_3 :: HappyAbsSyn
t4
t5
t6
t7
t8
[Arg a]
t10
t11
t12
t13
t14
t15
t16
t17
t18
t19
t20
t21
t22
t23
t24
t25
t26
t27
t28
t29
t30
t31
t32
t33
t34
t35
t36
t37
t38
t39
t40
(Name a)
t42
t43
t44
t45
t46
t47
t48
t49
t50
t51
t52
t53
(t58 -> (b, b) -> b)
t55
t56
t57
t58
(PreFunction a)
t60
t61
t62
t63
t64
t65
t66
t67
t68
t69
t70
t71
t72
t73
t74
t75
t76
t77
t78
t79
t80
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4836:9)
(Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)
|
4845 | ((PreF happy_var_1 (fst <happy_var_6 happy_var_5) [] [] happy_var_3 (snd <happy_var_6 happy_var_5) Nothing happy_var_6)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4845:125: error:
• Couldn't match expected type ‘Maybe (Expression a)’
with actual type ‘t58 -> (b, b) -> b’
• Probable cause: ‘happy_var_6’ is applied to too few arguments
In the 8th argument of ‘PreF’, namely ‘happy_var_6’
In the first argument of ‘happyIn59’, namely
‘((PreF
happy_var_1
(fst < happy_var_6 happy_var_5)
[]
[]
happy_var_3
(snd < happy_var_6 happy_var_5)
Nothing
happy_var_6))’
In the first argument of ‘HappyStk’, namely
‘happyIn59
((PreF
happy_var_1
(fst < happy_var_6 happy_var_5)
[]
[]
happy_var_3
(snd < happy_var_6 happy_var_5)
Nothing
happy_var_6))’
• Relevant bindings include
happy_var_6 :: t58 -> (b, b) -> b
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4843:40)
happy_var_5 :: t58
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4842:40)
happy_var_3 :: [Arg a]
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4841:39)
happy_var_1 :: Name a
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4840:43)
happyRest :: HappyStk
(HappyAbsSyn
t4
t5
t6
t7
t8
[Arg a]
t10
t11
t12
t13
t14
t15
t16
t17
t18
t19
t20
t21
t22
t23
t24
t25
t26
t27
t28
t29
t30
t31
t32
t33
t34
t35
t36
t37
t38
t39
t40
(Name a)
t42
t43
t44
t45
t46
t47
t48
t49
t50
t51
t52
t53
(t58 -> (b, b) -> b)
t55
t56
t57
t58
(PreFunction a)
t60
t61
t62
t63
t64
t65
t66
t67
t68
t69
t70
t71
t72
t73
t74
t75
t76
t77
t78
t79
t80)
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4839:9)
happy_x_1 :: HappyAbsSyn
t4
t5
t6
t7
t8
[Arg a]
t10
t11
t12
t13
t14
t15
t16
t17
t18
t19
t20
t21
t22
t23
t24
t25
t26
t27
t28
t29
t30
t31
t32
t33
t34
t35
t36
t37
t38
t39
t40
(Name a)
t42
t43
t44
t45
t46
t47
t48
t49
t50
t51
t52
t53
(t58 -> (b, b) -> b)
t55
t56
t57
t58
(PreFunction a)
t60
t61
t62
t63
t64
t65
t66
t67
t68
t69
t70
t71
t72
t73
t74
t75
t76
t77
t78
t79
t80
(bound at /home/vanessa/programming/haskell/done/ats/dist-newstyle/build/x86_64-linux/ghc-8.2.2/language-ats-1.0.1.0/opt/build/Language/ATS/Parser.hs:4838:9)
(Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)
|
4845 | ((PreF happy_var_1 (fst <happy_var_6 happy_var_5) [] [] happy_var_3 (snd <happy_var_6 happy_var_5) Nothing happy_var_6)
| ^^^^^^^^^^^
I didn't see anything in the manual indicating that this would not be allowed. I think it would be nice to have happy return some sort of error message before GHC does - the one I ran into was not particularly user-friendly.
Thanks!
Why was this closed? This is still an issue.
Reopening if it is still an issue.
The name of the issue is misleading
happy fails to generate valid Haskell when
<$>is used.
It generates valid Haskell, just not the Haskell that you expect. Happy treats <$> as < followed by $>, where $> is a reference much like $1, $2, $3, etc, that refers to the last (rightmost) item.
Something like fn <$> arg turns into fn <happy_var_n arg, which is of course valid Haskell – it is the use of the < operator.
One way to fix this would be to abstain from substituting $-references if they are preceded by a symbol that could be a Haskell operator.
I suggest we simply emit an error when <$> is used in code fragments. When the user meant <$>, they could use fmap instead. When the user meant < $> (as in 1 < $>), then the user can just insert a space.