我对ELM完全陌生。现在,我尝试将一些字符串(从json获取)转换为俄语翻译。例如意大利->Италия。
countryConvert : String -> String
countriesTransliterationMap country =
case country of
italy -> "Италия"
canada -> "Канада"
但是现在我收到了
Any value with this shape will be handled by a previous pattern, so it should be
removed.
我的代码有什么问题?
答案 0 :(得分:2)
您给出的代码不会产生您所说的错误。但是,如果我稍微清理一下,它将产生该错误:
italy : String
italy = "italy"
canada : String
canada = "canada"
countryConvert : String -> String
countryConvert country =
case country of
italy -> "Италия"
canada -> "Канада"
更准确地说,它会在Elm 0.18
中产生该错误。如果您尝试使用0.19
进行编译,则会得到更多信息错误:
$ 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!
这仍然有些神秘。要理解的关键是case
表达式有两个用途,有时有时会重叠:比较 单个值 或和 测试结构 (在0.18错误消息中用“形状”表示)和“分解”值-为该结构的各个部分提供本地名称。榆木指南中有nice simple example。
为了比较单个值,您必须在case表达式的每个子句中直接插入这些值。您使用的所有变量都假定为新声明,位于案例表达式的该子句的本地。
因此,在您的case表达式中,您与程序其余部分中的italy
和canada
具有的值不匹配。相反,您要声明两个刚发生在 上的新局部变量,它们分别命名为italy
和canada
。换句话说,您根本没有“分解” country
字符串-您所做的只是为它声明一个新的本地名称(italy
)。这就是0.19
抱怨阴影的原因。 (请参见this explanation,了解为什么阴影是错误的,而不仅仅是0.19中的警告。)
由于case表达式的子句之间也没有结构,因此0.18
实际上在抱怨您的两个case子句是相同的。一个将匹配任何字符串,并将其分配给新的局部变量italy
;另一个将也匹配任何字符串,并将其分配给新的局部变量canada
。
有效的替代方法:
您可以内联这些值:
countryConvert : String -> String
countryConvert country =
case country of
"italy" -> "Италия"
"canada" -> "Канада"
_ -> country
您可以使用简单的if-else构造:
countryConvert : String -> String
countryConvert country =
if country == italy then
"Италия"
else if country == canada then
"Канада"
else
country
或使用Dict
:
countries : Dict String String
countries =
fromList
[ ( "italy", "Италия" )
, ( "canada", "Канада" )
]
countryConvert : String -> String
countryConvert country =
case get country countries of
Just c ->
c
Nothing ->
country
请注意,使用此方法仍需要case
表达式。这是因为Dict.get
可能会传递给Dict中没有的键。因此,您可能会考虑将函数的返回类型也设置为Maybe String
,因此很明显,调用方可能会在您不知道如何翻译的国家/地区通过。决定在这种情况下该怎么做是呼叫者的责任。