ELM:音译字符串

时间:2018-11-11 04:07:40

标签: functional-programming elm

我对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.

我的代码有什么问题?

1 个答案:

答案 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表达式中,您与程序其余部分中的italycanada具有的值不匹配。相反,您要声明两个刚发生在 上的新局部变量,它们分别命名为italycanada。换句话说,您根本没有“分解” 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,因此很明显,调用方可能会在您不知道如何翻译的国家/地区通过。决定在这种情况下该怎么做是呼叫者的责任。