ELM : Transliterate string









up vote
1
down vote

favorite












I'm totally new in ELM. Now i trying to convert some string (that i get from json) to russian translation. For example italy -> Италия.



countryConvert : String -> String
countriesTransliterationMap country =
case country of
italy -> "Италия"
canada -> "Канада"


But now i receive



Any value with this shape will be handled by a previous pattern, so it should be
removed.


Whats wrong with my code?










share|improve this question

















  • 3




    You meant "italy" and "canada" (with quotes); not italy and canada (without quotes). Note you'll also need to add _ -> "default".
    – user633183
    Nov 11 at 4:39















up vote
1
down vote

favorite












I'm totally new in ELM. Now i trying to convert some string (that i get from json) to russian translation. For example italy -> Италия.



countryConvert : String -> String
countriesTransliterationMap country =
case country of
italy -> "Италия"
canada -> "Канада"


But now i receive



Any value with this shape will be handled by a previous pattern, so it should be
removed.


Whats wrong with my code?










share|improve this question

















  • 3




    You meant "italy" and "canada" (with quotes); not italy and canada (without quotes). Note you'll also need to add _ -> "default".
    – user633183
    Nov 11 at 4:39













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I'm totally new in ELM. Now i trying to convert some string (that i get from json) to russian translation. For example italy -> Италия.



countryConvert : String -> String
countriesTransliterationMap country =
case country of
italy -> "Италия"
canada -> "Канада"


But now i receive



Any value with this shape will be handled by a previous pattern, so it should be
removed.


Whats wrong with my code?










share|improve this question













I'm totally new in ELM. Now i trying to convert some string (that i get from json) to russian translation. For example italy -> Италия.



countryConvert : String -> String
countriesTransliterationMap country =
case country of
italy -> "Италия"
canada -> "Канада"


But now i receive



Any value with this shape will be handled by a previous pattern, so it should be
removed.


Whats wrong with my code?







functional-programming elm






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 4:07









Alex Straza

295




295







  • 3




    You meant "italy" and "canada" (with quotes); not italy and canada (without quotes). Note you'll also need to add _ -> "default".
    – user633183
    Nov 11 at 4:39













  • 3




    You meant "italy" and "canada" (with quotes); not italy and canada (without quotes). Note you'll also need to add _ -> "default".
    – user633183
    Nov 11 at 4:39








3




3




You meant "italy" and "canada" (with quotes); not italy and canada (without quotes). Note you'll also need to add _ -> "default".
– user633183
Nov 11 at 4:39





You meant "italy" and "canada" (with quotes); not italy and canada (without quotes). Note you'll also need to add _ -> "default".
– user633183
Nov 11 at 4:39













1 Answer
1






active

oldest

votes

















up vote
2
down vote













Your code as given does not produce the error you said it does. However, if I clean it up a bit, it will produce that error:



italy : String
italy = "italy"

canada : String
canada = "canada"

countryConvert : String -> String
countryConvert country =
case country of
italy -> "Италия"
canada -> "Канада"


To be more precise, it produces that error with Elm 0.18. If you try to compile with 0.19, you'll get a slightly more informative error:



$ elm make Countries.elm 
The name `italy` is first defined here:

5| italy = "italy"
^^^^^
But then it is defined AGAIN over here:

17| italy -> "Италия"
^^^^^
Think of a more helpful name for one of them and you should be all set!


This can still be a bit mysterious though. The key thing to understand is that case expressions have two purposes, which sometimes overlap: to compare individual values or to test structure ("shape", in the 0.18 error message's parlance) and "destructure" values -- giving local names to the parts of that structure. The Elm Guide has a nice simple example.



In order to compare individual values, you must have those values in-line in each clause of the case expression. Any variables that you use are assumed to be new declarations, local to that clause of the case expression.



So in your case expression, you aren't matching against the values that italy and canada have across the rest of your program. Instead, you're declaring two new local variables that just happen to also be named italy and canada. In other words, you haven't "taken apart" the country string at all -- all you've done is just declare a new local name for it (italy). And that's why 0.19 is complaining about shadowing. (See this explanation for why shadowing is an error rather than just a warning in 0.19.)



Since there is also no structural difference between the clauses of the case expression, 0.18 is effectively complaining that your two case clauses are identical. One will match any string an assign it to a new local variable italy; the other will also match any string, and assign it to a new local variable canada.



Alternatives that will work:



You can just inline the values:



countryConvert : String -> String
countryConvert country =
case country of
"italy" -> "Италия"
"canada" -> "Канада"
_ -> country


You can use a simple if-else construct:



countryConvert : String -> String
countryConvert country =
if country == italy then
"Италия"

else if country == canada then
"Канада"

else
country


Or use a Dict:



countries : Dict String String
countries =
fromList
[ ( "italy", "Италия" )
, ( "canada", "Канада" )
]


countryConvert : String -> String
countryConvert country =
case get country countries of
Just c ->
c

Nothing ->
country


Note that you do still need a case expression with this approach. That's because Dict.get might be passed a key that isn't in the Dict. So you might consider having your function's return type be Maybe String as well, so that it's clear that the caller might pass in a country you don't know how to translate. And that it's the caller's responsibility to decide what to do in that case.






share|improve this answer






















  • case can be used to also compare individual values, it's not just about comparing structure. Also the code does give the exact error mentioned in 0.19 (after you just change countriesTransliterationMap to countryConvert).
    – Markus Laire
    Nov 11 at 15:20











  • I guess the key is you can't compare top level values using case
    – Matt McHenry
    Nov 11 at 17:33










  • No, that's not right. @MarkusLaire I tried rephrasing, see if it makes more sense now.
    – Matt McHenry
    Nov 12 at 1:40










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53245759%2felm-transliterate-string%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote













Your code as given does not produce the error you said it does. However, if I clean it up a bit, it will produce that error:



italy : String
italy = "italy"

canada : String
canada = "canada"

countryConvert : String -> String
countryConvert country =
case country of
italy -> "Италия"
canada -> "Канада"


To be more precise, it produces that error with Elm 0.18. If you try to compile with 0.19, you'll get a slightly more informative error:



$ elm make Countries.elm 
The name `italy` is first defined here:

5| italy = "italy"
^^^^^
But then it is defined AGAIN over here:

17| italy -> "Италия"
^^^^^
Think of a more helpful name for one of them and you should be all set!


This can still be a bit mysterious though. The key thing to understand is that case expressions have two purposes, which sometimes overlap: to compare individual values or to test structure ("shape", in the 0.18 error message's parlance) and "destructure" values -- giving local names to the parts of that structure. The Elm Guide has a nice simple example.



In order to compare individual values, you must have those values in-line in each clause of the case expression. Any variables that you use are assumed to be new declarations, local to that clause of the case expression.



So in your case expression, you aren't matching against the values that italy and canada have across the rest of your program. Instead, you're declaring two new local variables that just happen to also be named italy and canada. In other words, you haven't "taken apart" the country string at all -- all you've done is just declare a new local name for it (italy). And that's why 0.19 is complaining about shadowing. (See this explanation for why shadowing is an error rather than just a warning in 0.19.)



Since there is also no structural difference between the clauses of the case expression, 0.18 is effectively complaining that your two case clauses are identical. One will match any string an assign it to a new local variable italy; the other will also match any string, and assign it to a new local variable canada.



Alternatives that will work:



You can just inline the values:



countryConvert : String -> String
countryConvert country =
case country of
"italy" -> "Италия"
"canada" -> "Канада"
_ -> country


You can use a simple if-else construct:



countryConvert : String -> String
countryConvert country =
if country == italy then
"Италия"

else if country == canada then
"Канада"

else
country


Or use a Dict:



countries : Dict String String
countries =
fromList
[ ( "italy", "Италия" )
, ( "canada", "Канада" )
]


countryConvert : String -> String
countryConvert country =
case get country countries of
Just c ->
c

Nothing ->
country


Note that you do still need a case expression with this approach. That's because Dict.get might be passed a key that isn't in the Dict. So you might consider having your function's return type be Maybe String as well, so that it's clear that the caller might pass in a country you don't know how to translate. And that it's the caller's responsibility to decide what to do in that case.






share|improve this answer






















  • case can be used to also compare individual values, it's not just about comparing structure. Also the code does give the exact error mentioned in 0.19 (after you just change countriesTransliterationMap to countryConvert).
    – Markus Laire
    Nov 11 at 15:20











  • I guess the key is you can't compare top level values using case
    – Matt McHenry
    Nov 11 at 17:33










  • No, that's not right. @MarkusLaire I tried rephrasing, see if it makes more sense now.
    – Matt McHenry
    Nov 12 at 1:40














up vote
2
down vote













Your code as given does not produce the error you said it does. However, if I clean it up a bit, it will produce that error:



italy : String
italy = "italy"

canada : String
canada = "canada"

countryConvert : String -> String
countryConvert country =
case country of
italy -> "Италия"
canada -> "Канада"


To be more precise, it produces that error with Elm 0.18. If you try to compile with 0.19, you'll get a slightly more informative error:



$ elm make Countries.elm 
The name `italy` is first defined here:

5| italy = "italy"
^^^^^
But then it is defined AGAIN over here:

17| italy -> "Италия"
^^^^^
Think of a more helpful name for one of them and you should be all set!


This can still be a bit mysterious though. The key thing to understand is that case expressions have two purposes, which sometimes overlap: to compare individual values or to test structure ("shape", in the 0.18 error message's parlance) and "destructure" values -- giving local names to the parts of that structure. The Elm Guide has a nice simple example.



In order to compare individual values, you must have those values in-line in each clause of the case expression. Any variables that you use are assumed to be new declarations, local to that clause of the case expression.



So in your case expression, you aren't matching against the values that italy and canada have across the rest of your program. Instead, you're declaring two new local variables that just happen to also be named italy and canada. In other words, you haven't "taken apart" the country string at all -- all you've done is just declare a new local name for it (italy). And that's why 0.19 is complaining about shadowing. (See this explanation for why shadowing is an error rather than just a warning in 0.19.)



Since there is also no structural difference between the clauses of the case expression, 0.18 is effectively complaining that your two case clauses are identical. One will match any string an assign it to a new local variable italy; the other will also match any string, and assign it to a new local variable canada.



Alternatives that will work:



You can just inline the values:



countryConvert : String -> String
countryConvert country =
case country of
"italy" -> "Италия"
"canada" -> "Канада"
_ -> country


You can use a simple if-else construct:



countryConvert : String -> String
countryConvert country =
if country == italy then
"Италия"

else if country == canada then
"Канада"

else
country


Or use a Dict:



countries : Dict String String
countries =
fromList
[ ( "italy", "Италия" )
, ( "canada", "Канада" )
]


countryConvert : String -> String
countryConvert country =
case get country countries of
Just c ->
c

Nothing ->
country


Note that you do still need a case expression with this approach. That's because Dict.get might be passed a key that isn't in the Dict. So you might consider having your function's return type be Maybe String as well, so that it's clear that the caller might pass in a country you don't know how to translate. And that it's the caller's responsibility to decide what to do in that case.






share|improve this answer






















  • case can be used to also compare individual values, it's not just about comparing structure. Also the code does give the exact error mentioned in 0.19 (after you just change countriesTransliterationMap to countryConvert).
    – Markus Laire
    Nov 11 at 15:20











  • I guess the key is you can't compare top level values using case
    – Matt McHenry
    Nov 11 at 17:33










  • No, that's not right. @MarkusLaire I tried rephrasing, see if it makes more sense now.
    – Matt McHenry
    Nov 12 at 1:40












up vote
2
down vote










up vote
2
down vote









Your code as given does not produce the error you said it does. However, if I clean it up a bit, it will produce that error:



italy : String
italy = "italy"

canada : String
canada = "canada"

countryConvert : String -> String
countryConvert country =
case country of
italy -> "Италия"
canada -> "Канада"


To be more precise, it produces that error with Elm 0.18. If you try to compile with 0.19, you'll get a slightly more informative error:



$ elm make Countries.elm 
The name `italy` is first defined here:

5| italy = "italy"
^^^^^
But then it is defined AGAIN over here:

17| italy -> "Италия"
^^^^^
Think of a more helpful name for one of them and you should be all set!


This can still be a bit mysterious though. The key thing to understand is that case expressions have two purposes, which sometimes overlap: to compare individual values or to test structure ("shape", in the 0.18 error message's parlance) and "destructure" values -- giving local names to the parts of that structure. The Elm Guide has a nice simple example.



In order to compare individual values, you must have those values in-line in each clause of the case expression. Any variables that you use are assumed to be new declarations, local to that clause of the case expression.



So in your case expression, you aren't matching against the values that italy and canada have across the rest of your program. Instead, you're declaring two new local variables that just happen to also be named italy and canada. In other words, you haven't "taken apart" the country string at all -- all you've done is just declare a new local name for it (italy). And that's why 0.19 is complaining about shadowing. (See this explanation for why shadowing is an error rather than just a warning in 0.19.)



Since there is also no structural difference between the clauses of the case expression, 0.18 is effectively complaining that your two case clauses are identical. One will match any string an assign it to a new local variable italy; the other will also match any string, and assign it to a new local variable canada.



Alternatives that will work:



You can just inline the values:



countryConvert : String -> String
countryConvert country =
case country of
"italy" -> "Италия"
"canada" -> "Канада"
_ -> country


You can use a simple if-else construct:



countryConvert : String -> String
countryConvert country =
if country == italy then
"Италия"

else if country == canada then
"Канада"

else
country


Or use a Dict:



countries : Dict String String
countries =
fromList
[ ( "italy", "Италия" )
, ( "canada", "Канада" )
]


countryConvert : String -> String
countryConvert country =
case get country countries of
Just c ->
c

Nothing ->
country


Note that you do still need a case expression with this approach. That's because Dict.get might be passed a key that isn't in the Dict. So you might consider having your function's return type be Maybe String as well, so that it's clear that the caller might pass in a country you don't know how to translate. And that it's the caller's responsibility to decide what to do in that case.






share|improve this answer














Your code as given does not produce the error you said it does. However, if I clean it up a bit, it will produce that error:



italy : String
italy = "italy"

canada : String
canada = "canada"

countryConvert : String -> String
countryConvert country =
case country of
italy -> "Италия"
canada -> "Канада"


To be more precise, it produces that error with Elm 0.18. If you try to compile with 0.19, you'll get a slightly more informative error:



$ elm make Countries.elm 
The name `italy` is first defined here:

5| italy = "italy"
^^^^^
But then it is defined AGAIN over here:

17| italy -> "Италия"
^^^^^
Think of a more helpful name for one of them and you should be all set!


This can still be a bit mysterious though. The key thing to understand is that case expressions have two purposes, which sometimes overlap: to compare individual values or to test structure ("shape", in the 0.18 error message's parlance) and "destructure" values -- giving local names to the parts of that structure. The Elm Guide has a nice simple example.



In order to compare individual values, you must have those values in-line in each clause of the case expression. Any variables that you use are assumed to be new declarations, local to that clause of the case expression.



So in your case expression, you aren't matching against the values that italy and canada have across the rest of your program. Instead, you're declaring two new local variables that just happen to also be named italy and canada. In other words, you haven't "taken apart" the country string at all -- all you've done is just declare a new local name for it (italy). And that's why 0.19 is complaining about shadowing. (See this explanation for why shadowing is an error rather than just a warning in 0.19.)



Since there is also no structural difference between the clauses of the case expression, 0.18 is effectively complaining that your two case clauses are identical. One will match any string an assign it to a new local variable italy; the other will also match any string, and assign it to a new local variable canada.



Alternatives that will work:



You can just inline the values:



countryConvert : String -> String
countryConvert country =
case country of
"italy" -> "Италия"
"canada" -> "Канада"
_ -> country


You can use a simple if-else construct:



countryConvert : String -> String
countryConvert country =
if country == italy then
"Италия"

else if country == canada then
"Канада"

else
country


Or use a Dict:



countries : Dict String String
countries =
fromList
[ ( "italy", "Италия" )
, ( "canada", "Канада" )
]


countryConvert : String -> String
countryConvert country =
case get country countries of
Just c ->
c

Nothing ->
country


Note that you do still need a case expression with this approach. That's because Dict.get might be passed a key that isn't in the Dict. So you might consider having your function's return type be Maybe String as well, so that it's clear that the caller might pass in a country you don't know how to translate. And that it's the caller's responsibility to decide what to do in that case.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 at 1:39

























answered Nov 11 at 14:36









Matt McHenry

14.2k65358




14.2k65358











  • case can be used to also compare individual values, it's not just about comparing structure. Also the code does give the exact error mentioned in 0.19 (after you just change countriesTransliterationMap to countryConvert).
    – Markus Laire
    Nov 11 at 15:20











  • I guess the key is you can't compare top level values using case
    – Matt McHenry
    Nov 11 at 17:33










  • No, that's not right. @MarkusLaire I tried rephrasing, see if it makes more sense now.
    – Matt McHenry
    Nov 12 at 1:40
















  • case can be used to also compare individual values, it's not just about comparing structure. Also the code does give the exact error mentioned in 0.19 (after you just change countriesTransliterationMap to countryConvert).
    – Markus Laire
    Nov 11 at 15:20











  • I guess the key is you can't compare top level values using case
    – Matt McHenry
    Nov 11 at 17:33










  • No, that's not right. @MarkusLaire I tried rephrasing, see if it makes more sense now.
    – Matt McHenry
    Nov 12 at 1:40















case can be used to also compare individual values, it's not just about comparing structure. Also the code does give the exact error mentioned in 0.19 (after you just change countriesTransliterationMap to countryConvert).
– Markus Laire
Nov 11 at 15:20





case can be used to also compare individual values, it's not just about comparing structure. Also the code does give the exact error mentioned in 0.19 (after you just change countriesTransliterationMap to countryConvert).
– Markus Laire
Nov 11 at 15:20













I guess the key is you can't compare top level values using case
– Matt McHenry
Nov 11 at 17:33




I guess the key is you can't compare top level values using case
– Matt McHenry
Nov 11 at 17:33












No, that's not right. @MarkusLaire I tried rephrasing, see if it makes more sense now.
– Matt McHenry
Nov 12 at 1:40




No, that's not right. @MarkusLaire I tried rephrasing, see if it makes more sense now.
– Matt McHenry
Nov 12 at 1:40

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53245759%2felm-transliterate-string%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3

Museum of Modern and Contemporary Art of Trento and Rovereto