on master help sign in
Improve the error for bad (++) usages

Try to make it as helpful as possible knowing that folks new to Elm are likely to see this many times while they get familiar with the syntax and with how strings and lists work.

commit20e9c3c82056aaaaf7b337bbd726d7815bb9ec76 authorEvan Czaplicki <evancz@users.noreply.github.com> dateSun 18 Feb 2018, 16:36 (9 years ago) parent6f9825f
2 files changed+114−29
src/Reporting/Error/Type.hs+110−29 src/Type/Error.hs+4
src/Reporting/Error/Type.hs+110−29
@@ -22,7 +22,6 @@ module Reporting.Error.Type
2222import Prelude hiding (round)
2323import Data.Monoid ((<>))
2424
25−import qualified AST.Module.Name as ModuleName
2625import qualified Data.Index as Index
2726import qualified Elm.Name as N
2827import qualified Reporting.Helpers as H
@@ -1009,7 +1008,7 @@ opLeftToDocs localizer category op tipe expected =
10091008 "<=" -> badCompLeft localizer category "<=" "left" tipe expected
10101009 ">=" -> badCompLeft localizer category ">=" "left" tipe expected
10111010
1012− "++" -> badAppend localizer category "left" tipe expected
1011+ "++" -> badAppendLeft localizer category tipe expected
10131012
10141013 "<|" ->
10151014 ( "The left side of (<|) needs to be a function so I can pipe arguments to it!"
@@ -1086,7 +1085,7 @@ opRightToDocs localizer category op tipe expected =
10861085 "/=" -> badEquality localizer "/=" tipe expected
10871086
10881087 "::" -> error "TODO"
1089− "++" -> EmphRight $ badAppend localizer category "right" tipe expected
1088+ "++" -> badAppendRight localizer category tipe expected
10901089
10911090 "<|" ->
10921091 EmphRight
@@ -1159,7 +1158,7 @@ isInt :: T.Type -> Bool
11591158isInt tipe =
11601159 case tipe of
11611160 T.Type home name [] ->
1162− home == ModuleName.basics && name == N.int
1161+ T.isInt home name
11631162
11641163 _ ->
11651164 False
@@ -1169,7 +1168,7 @@ isFloat :: T.Type -> Bool
11691168isFloat tipe =
11701169 case tipe of
11711170 T.Type home name [] ->
1172− home == ModuleName.basics && name == N.float
1171+ T.isFloat home name
11731172
11741173 _ ->
11751174 False
@@ -1179,7 +1178,7 @@ isString :: T.Type -> Bool
11791178isString tipe =
11801179 case tipe of
11811180 T.Type home name [] ->
1182− home == ModuleName.string && name == N.string
1181+ T.isString home name
11831182
11841183 _ ->
11851184 False
@@ -1189,7 +1188,7 @@ isList :: T.Type -> Bool
11891188isList tipe =
11901189 case tipe of
11911190 T.Type home name [_] ->
1192− home == ModuleName.list && name == N.list
1191+ T.isList home name
11931192
11941193 _ ->
11951194 False
@@ -1199,53 +1198,135 @@ isList tipe =
11991198-- BAD APPEND
12001199
12011200
1202−badAppend :: T.Localizer -> Category -> String -> T.Type -> T.Type -> (H.Doc, H.Doc)
1203−badAppend localizer category direction tipe expected =
1204− let
1205− maybeDetails =
1206− case tipe of
1207− T.Type home name []
1208− | ModuleName.basics == home && name == N.int -> Just ("ints", "String.fromInt")
1209− | ModuleName.basics == home && name == N.float -> Just ("floats", "String.fromFloat")
1201+data AppendType
1202+ = ANumber H.Doc H.Doc
1203+ | AString
1204+ | AList
1205+ | AOther
12101206
1211− T.FlexSuper T.Number _ ->
1212− Just ("numbers", "String.fromInt")
12131207
1214− _ ->
1215− Nothing
1216− in
1217− case maybeDetails of
1218− Just (things, stringFromThing) ->
1208+toAppendType :: T.Type -> AppendType
1209+toAppendType tipe =
1210+ case tipe of
1211+ T.Type home name _
1212+ | T.isInt home name -> ANumber "Int" "String.fromInt"
1213+ | T.isFloat home name -> ANumber "Float" "String.fromFloat"
1214+ | T.isString home name -> AString
1215+ | T.isList home name -> AList
1216+
1217+ T.FlexSuper T.Number _ -> ANumber "number" "String.fromInt"
1218+
1219+ _ -> AOther
1220+
1221+
1222+badAppendLeft :: T.Localizer -> Category -> T.Type -> T.Type -> (H.Doc, H.Doc)
1223+badAppendLeft localizer category tipe expected =
1224+ case toAppendType tipe of
1225+ ANumber thing stringFromThing ->
12191226 (
12201227 H.fillSep
1221− ["The","(++)","operator","is","for","appending",H.dullyellow "List","and"
1222− ,H.dullyellow "String","values,","not",H.dullyellow things,"like","this:"
1228+ ["The","(++)","operator","can","append"
1229+ ,H.dullyellow "List","and",H.dullyellow "String"
1230+ ,"values,","but","not",H.dullyellow thing,"values","like","this:"
12231231 ]
12241232 ,
12251233 H.fillSep
1226− ["Try","using",H.green stringFromThing,"to","turn","it","into","a"
1227− ,H.dullyellow "String" <> "?"
1234+ ["Try","using",H.green stringFromThing,"to","turn","it","into","a","string?"
1235+ ,"Or","put","it","in","[]","to","make","it","a","list?"
1236+ ,"Or","switch","to","the","(::)","operator?"
12281237 ]
12291238 )
12301239
1231− Nothing ->
1240+ _ ->
12321241 (
12331242 H.reflow $
12341243 "The (++) operator cannot append this type of value:"
12351244 ,
12361245 loneType localizer tipe expected
1237− ( H.reflow $ toDescription category $
1238− "The " <> direction <> " side of (++) is"
1246+ ( H.reflow $ toDescription category "I am seeing"
12391247 ,
12401248 [ H.fillSep
12411249 ["But","the","(++)","operator","is","only","for","appending"
12421250 ,H.dullyellow "List","and",H.dullyellow "String","values."
1251+ ,"Maybe","put","this","value","in","[]","to","make","it","a","list?"
12431252 ]
12441253 ]
12451254 )
12461255 )
12471256
12481257
1258+badAppendRight :: T.Localizer -> Category -> T.Type -> T.Type -> RightDocs
1259+badAppendRight localizer category tipe expected =
1260+ case (toAppendType expected, toAppendType tipe) of
1261+ (AString, ANumber thing stringFromThing) ->
1262+ EmphRight
1263+ (
1264+ H.fillSep
1265+ ["I","thought","I","was","appending",H.dullyellow "String","values","here,"
1266+ ,"not",H.dullyellow thing,"values","like","this:"
1267+ ]
1268+ ,
1269+ H.fillSep
1270+ ["Try","using",H.green stringFromThing
1271+ ,"to","turn","it","into","a","string?"
1272+ ]
1273+ )
1274+
1275+ (AList, ANumber thing _) ->
1276+ EmphRight
1277+ (
1278+ H.fillSep
1279+ ["I","thought","I","was","appending",H.dullyellow "List","values","here,"
1280+ ,"not",H.dullyellow thing,"values","like","this:"
1281+ ]
1282+ ,
1283+ H.reflow "Try putting it in [] to make it a list?"
1284+ )
1285+
1286+ (AString, AList) ->
1287+ EmphBoth
1288+ (
1289+ H.reflow $
1290+ "The (++) operator needs the same type of value on both sides:"
1291+ ,
1292+ H.fillSep
1293+ ["I","see","a",H.dullyellow "String","on","the","left","and","a"
1294+ ,H.dullyellow "List","on","the","right.","Which","should","it","be?"
1295+ ,"Does","the","string","need","[]","around","it","to","become","a","list?"
1296+ ]
1297+ )
1298+
1299+ (AList, AString) ->
1300+ EmphBoth
1301+ (
1302+ H.reflow $
1303+ "The (++) operator needs the same type of value on both sides:"
1304+ ,
1305+ H.fillSep
1306+ ["I","see","a",H.dullyellow "List","on","the","left","and","a"
1307+ ,H.dullyellow "String","on","the","right.","Which","should","it","be?"
1308+ ,"Does","the","string","need","[]","around","it","to","become","a","list?"
1309+ ]
1310+ )
1311+
1312+ (_,_) ->
1313+ EmphBoth
1314+ (
1315+ H.reflow $
1316+ "The (++) operator cannot append these two values:"
1317+ ,
1318+ typeComparison localizer tipe expected
1319+ (
1320+ "I already figured out that the left side of (++) is:"
1321+ ,
1322+ toDescription category $
1323+ "But this clashes with the right side, which is"
1324+ ,
1325+ []
1326+ )
1327+ )
1328+
1329+
12491330
12501331-- BAD MATH
12511332
src/Type/Error.hs+4
@@ -9,6 +9,10 @@ module Type.Error
99 , toDoc
1010 , toDiffDocs
1111 , Problem(..)
12+ , isInt
13+ , isFloat
14+ , isString
15+ , isList
1216 )
1317 where
1418