@@ -307,7 +307,7 @@ toPatternReport source localizer patternRegion category tipe expected =
309patternTypeComparison :: T.Localizer -> T.Type -> T.Type -> ( String, String, [H.Doc] ) -> H.Doc
309patternTypeComparison :: T.Localizer -> T.Type -> T.Type -> ( String, String, [H.Doc] ) -> H.Doc
310−patternTypeComparison localizer actual expected ( iAmSeeing, insteadOf, soHereAreSomeThoughts ) =
310+patternTypeComparison localizer actual expected ( iAmSeeing, insteadOf, contextHints ) =
312 (actualDoc, expectedDoc, problems) =
312 (actualDoc, expectedDoc, problems) =
313 T.toDiffDocs localizer actual expected
313 T.toDiffDocs localizer actual expected
@@ -318,8 +318,8 @@ patternTypeComparison localizer actual expected ( iAmSeeing, insteadOf, soHereAr
318 , H.reflow insteadOf
318 , H.reflow insteadOf
319 , H.indent 4 expectedDoc
319 , H.indent 4 expectedDoc
321− ++ soHereAreSomeThoughts
321+ ++ problemsToHint problems
322− ++ map problemToHints problems
322+ ++ contextHints
325toPatternDescription :: PCategory -> String -> String
325toPatternDescription :: PCategory -> String -> String
@@ -341,7 +341,7 @@ toPatternDescription category iAmTryingToMatch =
343typeComparison :: T.Localizer -> T.Type -> T.Type -> ( String, String, [H.Doc] ) -> H.Doc
343typeComparison :: T.Localizer -> T.Type -> T.Type -> ( String, String, [H.Doc] ) -> H.Doc
344−typeComparison localizer actual expected ( iAmSeeing, insteadOf, soHereAreSomeThoughts ) =
344+typeComparison localizer actual expected ( iAmSeeing, insteadOf, contextHints ) =
346 (actualDoc, expectedDoc, problems) =
346 (actualDoc, expectedDoc, problems) =
347 T.toDiffDocs localizer actual expected
347 T.toDiffDocs localizer actual expected
@@ -352,13 +352,22 @@ typeComparison localizer actual expected ( iAmSeeing, insteadOf, soHereAreSomeTh
352 , H.reflow insteadOf
352 , H.reflow insteadOf
353 , H.indent 4 expectedDoc
353 , H.indent 4 expectedDoc
355− ++ soHereAreSomeThoughts
355+ ++ problemsToHint problems
356− ++ map problemToHints problems
356+ ++ contextHints
359−indentType :: T.Localizer -> T.Type -> H.Doc
359+loneType :: T.Localizer -> T.Type -> T.Type -> ( H.Doc, [H.Doc] ) -> H.Doc
360−indentType localizer tipe =
360+loneType localizer actual expected ( iAmSeeing, furtherDetails ) =
361− H.indent 4 (H.dullyellow (T.toDoc localizer RT.None tipe))
361+ let
362+ (actualDoc, _, problems) =
363+ T.toDiffDocs localizer actual expected
367+ , H.indent 4 actualDoc
370+ ++ problemsToHint problems
364toDescription :: Category -> String -> String
373toDescription :: Category -> String -> String
@@ -389,19 +398,189 @@ toDescription category thatThingIs =
389 OpName _ -> thatThingIs <> ":"
398 OpName _ -> thatThingIs <> ":"
392−-- TODO be sure to avoid duplicate Problems (e.g. two instances of BadRigidVar)
401+problemsToHint :: [T.Problem] -> [H.Doc]
393−--
402+problemsToHint problems =
408+ problemToHint problem
394−problemToHints :: T.Problem -> H.Doc
411+problemToHint :: T.Problem -> [H.Doc]
395−problemToHints problem =
412+problemToHint problem =
396 case problem of
413 case problem of
397− T.FieldMismatch leftOnly rightOnly -> error "TODO FieldMismatch" leftOnly rightOnly
414+ T.FieldMismatch _ _ -> [] -- TODO do a better job?
398− T.IntFloat -> error "TODO IntFloat"
415+
399− T.MissingArgs numMissing -> error "TODO MissingArgs" numMissing
416+ T.IntFloat ->
400− T.ReturnMismatch -> error "TODO ReturnMismatch"
417+ [ H.fancyLink "Note" ["Read"] "implicit-casts"
401− T.TupleMismatch -> error "TODO TupleMismatch"
418+ ["to","learn","why","Elm","does","not","implicitly","convert"
402− T.BadFlexSuper x tipe -> error "TODO BadFlexSuper" x tipe
419+ ,"Ints","to","Floats.","Use",H.green "toFloat","and"
403− T.BadRigidVar x tipe -> error "TODO BadRigidVar" x tipe
420+ ,H.green "round","to","do","explicit","conversions."
404− T.BadRigidSuper x tipe -> error "TODO BadRigidSuper" x tipe
421+ ]
426+ ["Want","to","convert","an","Int","into","a","String?"
427+ ,"Use","the",H.green "String.fromInt","function!"
431+ T.StringFromFloat ->
433+ ["Want","to","convert","a","Float","into","a","String?"
434+ ,"Use","the",H.green "String.fromFloat","function!"
440+ ["Want","to","convert","a","String","into","an","Int?"
441+ ,"Use","the",H.green "String.toInt","function!"
447+ ["Want","to","convert","a","String","into","a","Float?"
448+ ,"Use","the",H.green "String.toFloat","function!"
454+ "Elm does not have “truthiness” such that ints and strings and lists\
455+ \ are automatically converted to booleans. Do that conversion explicitly!"
458+ T.AnythingFromMaybe ->
460+ ["Use",H.green "Maybe.withDefault","to","handle","possible","errors."
461+ ,"Longer","term,","it","is","usually","better","to","write","out","the"
462+ ,"full","`case`","though!"
467+ [ H.toSimpleHint "Did you forget to add [] around it?"
470+ T.MissingArgs _ -> []
471+ T.ReturnMismatch -> []
473+ T.BadFlexSuper super _ tipe ->
475+ T.Lambda _ _ _ -> badFlexSuper super
479+ T.FlexSuper s _ -> badDoubleFlexSuper super s
480+ T.RigidVar _y -> error "TODO"
481+ T.RigidSuper _s _y -> error "TODO"
482+ T.Type _ _ _ -> badFlexSuper super
483+ T.Record _ _ -> badFlexSuper super
484+ T.Unit -> badFlexSuper super
485+ T.Tuple _ _ _ -> badFlexSuper super
486+ T.Alias _ _ _ _ -> badFlexSuper super
488+ T.BadRigidVar x tipe ->
490+ T.Lambda _ _ _ -> badRigidVar x "a function"
494+ T.FlexSuper _s _y -> error "TODO"
495+ T.RigidVar y -> badDoubleRigid x y
496+ T.RigidSuper _ y -> badDoubleRigid x y
497+ T.Type _ name _ -> badRigidVar x ("a `" ++ N.toString name ++ "` value")
498+ T.Record _ _ -> badRigidVar x "a record"
499+ T.Unit -> badRigidVar x "a unit value"
500+ T.Tuple _ _ _ -> badRigidVar x "a tuple"
501+ T.Alias _ name _ _ -> badRigidVar x ("a `" ++ N.toString name ++ "` value")
503+ T.BadRigidSuper super x tipe ->
505+ T.Lambda _ _ _ -> badRigidSuper super "a function"
509+ T.FlexSuper _s _y -> error "TODO"
510+ T.RigidVar y -> badDoubleRigid x y
511+ T.RigidSuper _ y -> badDoubleRigid x y
512+ T.Type _ name _ -> badRigidSuper super ("a `" ++ N.toString name ++ "` value")
513+ T.Record _ _ -> badRigidSuper super "a record"
514+ T.Unit -> badRigidSuper super "a unit value"
515+ T.Tuple _ _ _ -> badRigidSuper super "a tuple"
516+ T.Alias _ name _ _ -> badRigidSuper super ("a `" ++ N.toString name ++ "` value")
519+badFlexSuper :: T.Super -> [H.Doc]
522+ T.Comparable -> [ H.toSimpleHint "Only ints, floats, chars, strings, lists, and tuples are comparable." ]
523+ T.Appendable -> [ H.toSimpleHint "Only strings and lists are appendable." ]
524+ T.CompAppend -> [ H.toSimpleHint "Only strings and lists are both comparable and appendable." ]
526+ [ H.toFancyHint ["Only",H.green "Int","and",H.green "Float","values","work","as","numbers."]
530+badRigidVar :: N.Name -> String -> [H.Doc]
531+badRigidVar name aThing =
533+ "Your type annotation uses type variable `" ++ N.toString name ++
534+ "` which means ANY type of value can flow through, but your code is saying it specifically wants "
535+ ++ aThing ++ ". Maybe change your type annotation to\
536+ \ be more specific? Maybe change the code to be more general?"
537+ , H.reflowLink "Read" "type-annotations" "for more advice!"
541+badDoubleFlexSuper :: T.Super -> T.Super -> [H.Doc]
542+badDoubleFlexSuper s1 s2 =
550+ T.Number -> error "TODO" whatever s1 s2
551+ T.Comparable -> error "TODO" whatever s1 s2
552+ T.Appendable -> error "TODO" whatever s1 s2
553+ T.CompAppend -> error "TODO" whatever s1 s2
556+badRigidSuper :: T.Super -> String -> [H.Doc]
557+badRigidSuper super aThing =
559+ (superType, manyThings) =
561+ T.Number -> ("number", "ints AND floats")
562+ T.Comparable -> ("comparable", "ints, floats, chars, strings, lists, and tuples")
563+ T.Appendable -> ("appendable", "strings AND lists")
564+ T.CompAppend -> ("compappend", "strings AND lists")
567+ "The `" ++ superType ++ "` in your type annotation is saying that " ++
568+ manyThings ++ " can flow through, but your code is saying it specifically wants "
569+ ++ aThing ++ ". Maybe change your type annotation to\
570+ \ be more specific? Maybe change the code to be more general?"
571+ , H.reflowLink "Read" "type-annotations" "for more advice!"
575+badDoubleRigid :: N.Name -> N.Name -> [H.Doc]
578+ "Your type annotation uses `" ++ N.toString x ++ "` and `" ++ N.toString y ++
579+ "` as separate type variables. Your code seems to be saying they are the\
580+ \ same though! Maybe they should be the same in your type annotation?\
581+ \ Maybe your code uses them in a weird way?"
582+ , H.reflowLink "Read" "type-annotations" "for more advice!"
@@ -423,9 +602,7 @@ toExprReport source localizer exprRegion category tipe expected =
424 "But you are trying to use it as:"
603 "But you are trying to use it as:"
@@ -491,15 +668,16 @@ toExprReport source localizer exprRegion category tipe expected =
492 "I do not know how to negate this type of value:"
669 "I do not know how to negate this type of value:"
494− H.stack
671+ loneType localizer tipe expectedType
495− [ H.reflow $ toDescription category "It is"
673+ H.reflow $ toDescription category "It is"
496− , indentType localizer tipe
674+ ,
497− , H.fillSep
675+ [ H.fillSep
498− ["But","I","only","now","how","to","negate"
676+ ["But","I","only","now","how","to","negate"
499− ,H.dullyellow "Int","and",H.dullyellow "Float","values."
677+ ,H.dullyellow "Int","and",H.dullyellow "Float","values."
505 OpLeft op ->
683 OpLeft op ->
@@ -519,14 +697,13 @@ toExprReport source localizer exprRegion category tipe expected =
520 "This `if` condition does not evaluate to a boolean value, True or False."
698 "This `if` condition does not evaluate to a boolean value, True or False."
522− H.stack
700+ loneType localizer tipe expectedType
523− [ H.reflow $ toDescription category "It is"
702+ H.reflow $ toDescription category "It is"
524− , indentType localizer tipe
703+ ,
525− , H.fillSep ["But","I","need","this","`if`","condition","to","be","a",H.dullyellow "Bool","value."]
704+ [ H.fillSep ["But","I","need","this","`if`","condition","to","be","a",H.dullyellow "Bool","value."]
526− , H.toSimpleHint $
705+ ]
527− "Elm does not have “truthiness” such that ints and strings and lists\
706+ )
528− \ are automatically converted to booleans. Do that conversion explicitly!"
532 IfBranch index ->
709 IfBranch index ->
@@ -698,13 +875,16 @@ toExprReport source localizer exprRegion category tipe expected =
698 H.reflow $
875 H.reflow $
699 "This record does not have a `" <> N.toString field <> "` field:"
876 "This record does not have a `" <> N.toString field <> "` field:"
701− H.stack $
878+ loneType localizer tipe expectedType
703− "It is a record with this type:"
880+ H.reflow $ "It is a record with this type:"
704− , indentType localizer tipe
881+ ,
705− , H.reflow $
882+ [ H.fillSep
883+ ["Is","the",H.dullyellow ("." <> H.nameToDoc field)
706− "So maybe the ." <> N.toString field <> " field access is misspelled?"
884+ ,"field","access","is","misspelled?"
@@ -712,12 +892,14 @@ toExprReport source localizer exprRegion category tipe expected =
712 H.reflow $
892 H.reflow $
713 "This is not a record, so it has no fields to access!"
893 "This is not a record, so it has no fields to access!"
715− H.stack
895+ loneType localizer tipe expectedType
716− [ H.reflow $ toDescription category "It is"
896+ ( H.reflow $ toDescription category "It is"
717− , indentType localizer tipe
718− , H.fillSep
897+ , [ H.fillSep
898+ ["But","I","need","a","record","with","a"
719− ["But","I","need","a","record","with","a",H.dullyellow (H.nameToDoc field),"field!"]
899+ ,H.dullyellow (H.nameToDoc field),"field!"
723 RecordUpdate ->
905 RecordUpdate ->
@@ -744,11 +926,11 @@ toExprReport source localizer exprRegion category tipe expected =
745 "The record update syntax does not work with this value:"
927 "The record update syntax does not work with this value:"
747− H.stack
929+ loneType localizer tipe expectedType
748− [ H.reflow $ toDescription category "It is"
930+ ( H.reflow $ toDescription category "It is"
749− , indentType localizer tipe
750− , H.reflow $ "But I need some kind of record here!"
931+ , [ H.reflow $ "But I need some kind of record here!"
754 Destructure ->
936 Destructure ->
@@ -787,36 +969,38 @@ countArgs tipe =
789opLeftToDocs :: T.Localizer -> Category -> N.Name -> T.Type -> T.Type -> (H.Doc, H.Doc)
971opLeftToDocs :: T.Localizer -> Category -> N.Name -> T.Type -> T.Type -> (H.Doc, H.Doc)
790−opLeftToDocs localizer category op tipe expectedType =
972+opLeftToDocs localizer category op tipe expected =
791 case op of
973 case op of
793 | isString tipe -> badStringAdd
975 | isString tipe -> badStringAdd
794− | isList tipe -> badListAdd localizer category "left" tipe
976+ | isList tipe -> badListAdd localizer category "left" tipe expected
795− | otherwise -> badMath localizer category "Addition" "left" "+" tipe []
977+ | otherwise -> badMath localizer category "Addition" "left" "+" tipe expected []
798− | isList tipe -> badListMul localizer category "left" tipe
980+ | isList tipe -> badListMul localizer category "left" tipe expected
799− | otherwise -> badMath localizer category "Multiplication" "left" "*" tipe []
981+ | otherwise -> badMath localizer category "Multiplication" "left" "*" tipe expected []
801− "-" -> badMath localizer category "Subtraction" "left" "-" tipe []
983+ "-" -> badMath localizer category "Subtraction" "left" "-" tipe expected []
802− "^" -> badMath localizer category "Exponentiation" "left" "^" tipe []
984+ "^" -> badMath localizer category "Exponentiation" "left" "^" tipe expected []
803− "/" -> badFDiv localizer "left" tipe
985+ "/" -> badFDiv localizer "left" tipe expected
804− "//" -> badIDiv localizer "left" tipe
986+ "//" -> badIDiv localizer "left" tipe expected
805− "&&" -> badBool localizer "&&" "left" tipe
987+ "&&" -> badBool localizer "&&" "left" tipe expected
806− "||" -> badBool localizer "||" "left" tipe
988+ "||" -> badBool localizer "||" "left" tipe expected
807− "<" -> badCompLeft localizer category "<" "left" tipe
989+ "<" -> badCompLeft localizer category "<" "left" tipe expected
808− ">" -> badCompLeft localizer category ">" "left" tipe
990+ ">" -> badCompLeft localizer category ">" "left" tipe expected
809− "<=" -> badCompLeft localizer category "<=" "left" tipe
991+ "<=" -> badCompLeft localizer category "<=" "left" tipe expected
810− ">=" -> badCompLeft localizer category ">=" "left" tipe
992+ ">=" -> badCompLeft localizer category ">=" "left" tipe expected
994+ "++" -> badAppend localizer category "left" tipe expected
813 ( "The left side of (<|) needs to be a function so I can pipe arguments to it!"
997 ( "The left side of (<|) needs to be a function so I can pipe arguments to it!"
815− H.stack
999+ loneType localizer tipe expected
816− [ H.reflow $ toDescription category "I am seeing"
1000+ ( H.reflow $ toDescription category "I am seeing"
817− , indentType localizer tipe
818− , H.reflow $ "This needs to be some kind of function though!"
1001+ , [ H.reflow $ "This needs to be some kind of function though!"
@@ -824,7 +1008,7 @@ opLeftToDocs localizer category op tipe expectedType =
824 H.reflow $
1008 H.reflow $
825 "The left argument of (" <> N.toString op <> ") is causing problems:"
1009 "The left argument of (" <> N.toString op <> ") is causing problems:"
827− typeComparison localizer tipe expectedType
1011+ typeComparison localizer tipe expected
829 toDescription category "The left argument is"
1013 toDescription category "The left argument is"
@@ -845,41 +1029,46 @@ data RightDocs
847opRightToDocs :: T.Localizer -> Category -> N.Name -> T.Type -> T.Type -> RightDocs
1031opRightToDocs :: T.Localizer -> Category -> N.Name -> T.Type -> T.Type -> RightDocs
848−opRightToDocs localizer category op tipe expectedType =
1032+opRightToDocs localizer category op tipe expected =
849 case op of
1033 case op of
851− | isInt tipe -> badCast op FloatInt
1035+ | isFloat expected && isInt tipe -> badCast op FloatInt
852− | isFloat tipe -> badCast op IntFloat
1036+ | isInt expected && isFloat tipe -> badCast op IntFloat
853 | isString tipe -> EmphRight $ badStringAdd
1037 | isString tipe -> EmphRight $ badStringAdd
854− | isList tipe -> EmphRight $ badListAdd localizer category "right" tipe
1038+ | isList tipe -> EmphRight $ badListAdd localizer category "right" tipe expected
855− | otherwise -> EmphRight $ badMath localizer category "Addition" "right" "+" tipe []
1039+ | otherwise -> EmphRight $ badMath localizer category "Addition" "right" "+" tipe expected []
858− | isInt tipe -> badCast op FloatInt
1042+ | isFloat expected && isInt tipe -> badCast op FloatInt
859− | isFloat tipe -> badCast op IntFloat
1043+ | isInt expected && isFloat tipe -> badCast op IntFloat
860− | isList tipe -> EmphRight $ badListMul localizer category "right" tipe
1044+ | isList tipe -> EmphRight $ badListMul localizer category "right" tipe expected
861− | otherwise -> EmphRight $ badMath localizer category "Multiplication" "right" "*" tipe []
1045+ | otherwise -> EmphRight $ badMath localizer category "Multiplication" "right" "*" tipe expected []
864− | isInt tipe -> badCast op FloatInt
1048+ | isFloat expected && isInt tipe -> badCast op FloatInt
865− | isFloat tipe -> badCast op IntFloat
1049+ | isInt expected && isFloat tipe -> badCast op IntFloat
866− | otherwise -> EmphRight $ badMath localizer category "Subtraction" "right" "-" tipe []
1051+ EmphRight $ badMath localizer category "Subtraction" "right" "-" tipe expected []
869− | isInt tipe -> badCast op FloatInt
1054+ | isFloat expected && isInt tipe -> badCast op FloatInt
870− | isFloat tipe -> badCast op IntFloat
1055+ | isInt expected && isFloat tipe -> badCast op IntFloat
871− | otherwise -> EmphRight $ badMath localizer category "Exponentiation" "right" "^" tipe []
1057+ EmphRight $ badMath localizer category "Exponentiation" "right" "^" tipe expected []
873− "/" -> EmphRight $ badFDiv localizer "right" tipe
1059+ "/" -> EmphRight $ badFDiv localizer "right" tipe expected
874− "//" -> EmphRight $ badIDiv localizer "right" tipe
1060+ "//" -> EmphRight $ badIDiv localizer "right" tipe expected
875− "&&" -> EmphRight $ badBool localizer "&&" "right" tipe
1061+ "&&" -> EmphRight $ badBool localizer "&&" "right" tipe expected
876− "||" -> EmphRight $ badBool localizer "||" "right" tipe
1062+ "||" -> EmphRight $ badBool localizer "||" "right" tipe expected
877− "<" -> badCompRight localizer "<" tipe expectedType
1063+ "<" -> badCompRight localizer "<" tipe expected
878− ">" -> badCompRight localizer ">" tipe expectedType
1064+ ">" -> badCompRight localizer ">" tipe expected
879− "<=" -> badCompRight localizer "<=" tipe expectedType
1065+ "<=" -> badCompRight localizer "<=" tipe expected
880− ">=" -> badCompRight localizer ">=" tipe expectedType
1066+ ">=" -> badCompRight localizer ">=" tipe expected
881− "==" -> badEquality localizer "==" tipe expectedType
1067+ "==" -> badEquality localizer "==" tipe expected
882− "/=" -> badEquality localizer "/=" tipe expectedType
1068+ "/=" -> badEquality localizer "/=" tipe expected
1070+ "::" -> error "TODO"
1071+ "++" -> EmphRight $ badAppend localizer category "right" tipe expected
885 EmphRight
1074 EmphRight
@@ -887,7 +1076,7 @@ opRightToDocs localizer category op tipe expectedType =
887 H.reflow $
1076 H.reflow $
888 "I cannot send this through the (<|) pipe:"
1077 "I cannot send this through the (<|) pipe:"
890− typeComparison localizer tipe expectedType
1079+ typeComparison localizer tipe expected
892 toDescription category "You are providing"
1081 toDescription category "You are providing"
@@ -898,7 +1087,7 @@ opRightToDocs localizer category op tipe expectedType =
901− case (tipe, expectedType) of
1090+ case (tipe, expected) of
902 (T.Lambda expectedArgType _ _, T.Lambda argType _ _) ->
1091 (T.Lambda expectedArgType _ _, T.Lambda argType _ _) ->
903 EmphRight
1092 EmphRight
@@ -919,11 +1108,11 @@ opRightToDocs localizer category op tipe expectedType =
920 "The right side of (|>) needs to be a function so I can pipe arguments to it!"
1109 "The right side of (|>) needs to be a function so I can pipe arguments to it!"
922− H.stack
1111+ loneType localizer tipe expected
923− [ H.reflow $ toDescription category $
1112+ ( H.reflow $ toDescription category $
924− "Instead of a function, I am seeing "
1113+ "But instead of a function, I am seeing "
925− , indentType localizer tipe
@@ -932,7 +1121,7 @@ opRightToDocs localizer category op tipe expectedType =
932 H.reflow $
1121 H.reflow $
933 "The right argument of (" <> N.toString op <> ") is causing problems."
1122 "The right argument of (" <> N.toString op <> ") is causing problems."
935− typeComparison localizer tipe expectedType
1124+ typeComparison localizer tipe expected
937 toDescription category "The right argument is"
1126 toDescription category "The right argument is"
@@ -989,6 +1178,57 @@ isList tipe =
1184+badAppend :: T.Localizer -> Category -> String -> T.Type -> T.Type -> (H.Doc, H.Doc)
1185+badAppend localizer category direction tipe expected =
1189+ T.Type home name []
1190+ | ModuleName.basics == home && name == N.int -> Just ("ints", "String.fromInt")
1191+ | ModuleName.basics == home && name == N.float -> Just ("floats", "String.fromFloat")
1193+ T.FlexSuper T.Number _ ->
1194+ Just ("numbers", "String.fromInt")
1199+ case maybeDetails of
1200+ Just (things, stringFromThing) ->
1203+ ["The","(++)","operator","is","for","appending",H.dullyellow "List","and"
1204+ ,H.dullyellow "String","values,","not",H.dullyellow things,"like","this:"
1208+ ["Try","using",H.green stringFromThing,"to","turn","it","into","a"
1209+ ,H.dullyellow "String" <> "?"
1216+ "The (++) operator cannot append this type of value:"
1218+ loneType localizer tipe expected
1219+ ( H.reflow $ toDescription category $
1220+ "The " <> direction <> " side of (++) is"
1223+ ["But","the","(++)","operator","is","only","for","appending"
1224+ ,H.dullyellow "List","and",H.dullyellow "String","values."
992-- BAD MATH
1232-- BAD MATH
@@ -1050,28 +1290,30 @@ badStringAdd =
1053−badListAdd :: T.Localizer -> Category -> String -> T.Type -> (H.Doc, H.Doc)
1293+badListAdd :: T.Localizer -> Category -> String -> T.Type -> T.Type -> (H.Doc, H.Doc)
1054−badListAdd localizer category direction tipe =
1294+badListAdd localizer category direction tipe expected =
1056 "I cannot do addition with lists:"
1296 "I cannot do addition with lists:"
1058− H.stack
1298+ loneType localizer tipe expected
1059− [ H.reflow $ toDescription category $
1300+ H.reflow $ toDescription category $
1060 "The " <> direction <> " side of (+) is"
1301 "The " <> direction <> " side of (+) is"
1061− , indentType localizer tipe
1302+ ,
1062− , H.fillSep
1303+ [ H.fillSep
1063− ["But","(+)","only","works","with",H.dullyellow "Int","and",H.dullyellow "Float","values."
1304+ ["But","(+)","only","works","with",H.dullyellow "Int","and",H.dullyellow "Float","values."
1065− , H.toFancyHint
1306+ , H.toFancyHint
1066− ["Switch","to","the",H.green "(++)","operator","to","append","lists!"
1307+ ["Switch","to","the",H.green "(++)","operator","to","append","lists!"
1072−badListMul :: T.Localizer -> Category -> String -> T.Type -> (H.Doc, H.Doc)
1314+badListMul :: T.Localizer -> Category -> String -> T.Type -> T.Type -> (H.Doc, H.Doc)
1073−badListMul localizer category direction tipe =
1315+badListMul localizer category direction tipe expected =
1074− badMath localizer category "Multiplication" direction "*" tipe
1316+ badMath localizer category "Multiplication" direction "*" tipe expected
1076 H.toFancyHint
1318 H.toFancyHint
1077 [ "Maybe", "you", "want"
1319 [ "Maybe", "you", "want"
@@ -1081,27 +1323,28 @@ badListMul localizer category direction tipe =
1084−badMath :: T.Localizer -> Category -> String -> String -> String -> T.Type -> [H.Doc] -> (H.Doc, H.Doc)
1326+badMath :: T.Localizer -> Category -> String -> String -> String -> T.Type -> T.Type -> [H.Doc] -> (H.Doc, H.Doc)
1085−badMath localizer category operation direction op tipe otherHints =
1327+badMath localizer category operation direction op tipe expected otherHints =
1087 H.reflow $
1329 H.reflow $
1088 operation ++ " does not work with this value:"
1330 operation ++ " does not work with this value:"
1090− H.stack $
1332+ loneType localizer tipe expected
1091− [ H.reflow $ toDescription category $
1333+ ( H.reflow $ toDescription category $
1092 "The " <> direction <> " side of (" <> op <> ") is"
1334 "The " <> direction <> " side of (" <> op <> ") is"
1093− , indentType localizer tipe
1335+ ,
1094− , H.fillSep
1336+ [ H.fillSep
1095− ["But","(" <> H.text op <> ")","only","works","with"
1337+ ["But","(" <> H.text op <> ")","only","works","with"
1096− ,H.dullyellow "Int","and",H.dullyellow "Float","values."
1338+ ,H.dullyellow "Int","and",H.dullyellow "Float","values."
1099− ++ otherHints
1341+ ++ otherHints
1103−badFDiv :: T.Localizer -> H.Doc -> T.Type -> (H.Doc, H.Doc)
1346+badFDiv :: T.Localizer -> H.Doc -> T.Type -> T.Type -> (H.Doc, H.Doc)
1104−badFDiv localizer direction tipe =
1347+badFDiv localizer direction tipe expected =
1106 H.reflow $
1349 H.reflow $
1107 "The (/) operator is specifically for floating-point division:"
1350 "The (/) operator is specifically for floating-point division:"
@@ -1122,19 +1365,20 @@ badFDiv localizer direction tipe =
1125− H.stack
1368+ loneType localizer tipe expected
1126− [ H.fillSep
1370+ H.fillSep
1127 ["The",direction,"side","of","(/)","must","be","a"
1371 ["The",direction,"side","of","(/)","must","be","a"
1128 ,H.dullyellow "Float" <> ","
1372 ,H.dullyellow "Float" <> ","
1129 ,"but","instead","I","am","seeing:"
1373 ,"but","instead","I","am","seeing:"
1131− , indentType localizer tipe
1375+ , []
1136−badIDiv :: T.Localizer -> H.Doc -> T.Type -> (H.Doc, H.Doc)
1380+badIDiv :: T.Localizer -> H.Doc -> T.Type -> T.Type -> (H.Doc, H.Doc)
1137−badIDiv localizer direction tipe =
1381+badIDiv localizer direction tipe expected =
1139 H.reflow $
1383 H.reflow $
1140 "The (//) operator is specifically for integer division:"
1384 "The (//) operator is specifically for integer division:"
@@ -1157,14 +1401,15 @@ badIDiv localizer direction tipe =
1157 , H.link "Note" "Read" "implicit-casts" "to learn why Elm does not implicitly convert Ints to Floats."
1401 , H.link "Note" "Read" "implicit-casts" "to learn why Elm does not implicitly convert Ints to Floats."
1160− H.stack
1404+ loneType localizer tipe expected
1161− [ H.fillSep
1406+ H.fillSep
1162 ["The",direction,"side","of","(//)","must","be","an"
1407 ["The",direction,"side","of","(//)","must","be","an"
1163 ,H.dullyellow "Int" <> ","
1408 ,H.dullyellow "Int" <> ","
1164 ,"but","instead","I","am","seeing:"
1409 ,"but","instead","I","am","seeing:"
1166− , indentType localizer tipe
1411+ , []
@@ -1172,22 +1417,21 @@ badIDiv localizer direction tipe =
1172-- BAD BOOLS
1417-- BAD BOOLS
1175−badBool :: T.Localizer -> H.Doc -> H.Doc -> T.Type -> (H.Doc, H.Doc)
1420+badBool :: T.Localizer -> H.Doc -> H.Doc -> T.Type -> T.Type -> (H.Doc, H.Doc)
1176−badBool localizer op direction tipe =
1421+badBool localizer op direction tipe expected =
1178 H.reflow $
1423 H.reflow $
1179 "I am struggling with this boolean operation:"
1424 "I am struggling with this boolean operation:"
1181− H.stack
1426+ loneType localizer tipe expected
1182− [ H.fillSep
1428+ H.fillSep
1183 ["Both","sides","of","(" <> op <> ")","must","be"
1429 ["Both","sides","of","(" <> op <> ")","must","be"
1184 ,H.dullyellow "Bool","values,","but","the",direction,"side","is:"
1430 ,H.dullyellow "Bool","values,","but","the",direction,"side","is:"
1186− , indentType localizer tipe
1432+ ,
1188− "Elm does not have “truthiness” such that ints and strings and lists are\
1189− \ automatically converted to booleans. Do that conversion explicitly!"
@@ -1195,38 +1439,40 @@ badBool localizer op direction tipe =
1195-- BAD COMPARISON
1439-- BAD COMPARISON
1198−badCompLeft :: T.Localizer -> Category -> String -> String -> T.Type -> (H.Doc, H.Doc)
1442+badCompLeft :: T.Localizer -> Category -> String -> String -> T.Type -> T.Type -> (H.Doc, H.Doc)
1199−badCompLeft localizer category op direction tipe =
1443+badCompLeft localizer category op direction tipe expected =
1201 H.reflow $
1445 H.reflow $
1202 "I cannot do a comparison with this value:"
1446 "I cannot do a comparison with this value:"
1204− H.stack
1448+ loneType localizer tipe expected
1205− [ H.reflow $ toDescription category $
1450+ H.reflow $ toDescription category $
1206 "The " <> direction <> " side of (" <> op <> ") is"
1451 "The " <> direction <> " side of (" <> op <> ") is"
1207− , indentType localizer tipe
1452+ ,
1208− , H.fillSep
1453+ [ H.fillSep
1209− ["But","(" <> H.text op <> ")","only","works","on"
1454+ ["But","(" <> H.text op <> ")","only","works","on"
1210− ,H.dullyellow "Int" <> ","
1455+ ,H.dullyellow "Int" <> ","
1211− ,H.dullyellow "Float" <> ","
1456+ ,H.dullyellow "Float" <> ","
1212− ,H.dullyellow "Char" <> ","
1457+ ,H.dullyellow "Char" <> ","
1214− ,H.dullyellow "String"
1459+ ,H.dullyellow "String"
1215− ,"values.","If","you","want","to","get","crazy,","it","will","work","on"
1460+ ,"values.","If","you","want","to","get","crazy,","it","will","work","on"
1216− ,"lists","and","tuples","of","comparable","values","as","well."
1461+ ,"lists","and","tuples","of","comparable","values","as","well."
1222badCompRight :: T.Localizer -> String -> T.Type -> T.Type -> RightDocs
1468badCompRight :: T.Localizer -> String -> T.Type -> T.Type -> RightDocs
1223−badCompRight localizer op tipe expectedType =
1469+badCompRight localizer op tipe expected =
1224 EmphBoth
1470 EmphBoth
1226 H.reflow $
1472 H.reflow $
1227 "I need both sides of (" <> op <> ") to be the same type:"
1473 "I need both sides of (" <> op <> ") to be the same type:"
1229− typeComparison localizer expectedType tipe
1475+ typeComparison localizer expected tipe
1231 "The left side of is:"
1477 "The left side of is:"
@@ -1244,19 +1490,19 @@ badCompRight localizer op tipe expectedType =
1246badEquality :: T.Localizer -> String -> T.Type -> T.Type -> RightDocs
1492badEquality :: T.Localizer -> String -> T.Type -> T.Type -> RightDocs
1247−badEquality localizer op tipe expectedType =
1493+badEquality localizer op tipe expected =
1248 EmphBoth
1494 EmphBoth
1250 H.reflow $
1496 H.reflow $
1251 "I need both sides of (" <> op <> ") to be the same type:"
1497 "I need both sides of (" <> op <> ") to be the same type:"
1253− typeComparison localizer expectedType tipe
1499+ typeComparison localizer expected tipe
1255 "The left side of is:"
1501 "The left side of is:"
1257 "But the right side is:"
1503 "But the right side is:"
1259− if isFloat tipe || isFloat expectedType then
1505+ if isFloat tipe || isFloat expected then
1260 [ H.toSimpleNote $
1506 [ H.toSimpleNote $
1261 "Equality on floats is not 100% reliable due to the design of IEEE 754. I\
1507 "Equality on floats is not 100% reliable due to the design of IEEE 754. I\
1262 \ recommend a check like (abs (x - y) < 0.0001) instead."
1508 \ recommend a check like (abs (x - y) < 0.0001) instead."
@@ -1285,7 +1531,7 @@ toInfiniteReport source localizer region name overallType =
1285 [ H.reflow $
1531 [ H.reflow $
1286 "Here is my best effort at writing down the type. You will see ∞ for\
1532 "Here is my best effort at writing down the type. You will see ∞ for\
1287 \ parts of the type that repeat something already printed out infinitely."
1533 \ parts of the type that repeat something already printed out infinitely."
1288− , indentType localizer overallType
1534+ , H.indent 4 (H.dullyellow (T.toDoc localizer RT.None overallType))
1289 , H.reflowLink
1535 , H.reflowLink
1290 "Staring at the type is usually not so helpful, so I recommend reading the hints at"
1536 "Staring at the type is usually not so helpful, so I recommend reading the hints at"
1291 "infinite-type"
1537 "infinite-type"