将字符串中的每个其他字母大写 - 列表中的 take / drop 与 head / tail

Capitalize Every Other Letter in a String -- take / drop versus head / tail for Lists

我花了一两个下午的时间在我的电脑上戳来戳去,好像我以前从未见过一样。今天的话题列表


练习是获取一个字符串,每隔一个字母大写。我没走多远...

让我们列出一个列表 x = String.toList "abcde" 并尝试对其进行分析。如果我们添加 take 1drop 1 的结果,我们会得到原始列表

> x = String.toList "abcde"
['a','b','c','d','e'] : List Char
> (List.take 1 x) ++ (List.drop 1 x)
['a','b','c','d','e'] : List Char

我以为 headtail 做了同样的事情,但我收到一条大错误消息:

> [List.head x] ++ (List.tail x)
==================================== ERRORS ====================================

-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm

The right argument of (++) is causing a type mismatch.

7│   [List.head x] ++ (List.tail x)
                       ^^^^^^^^^^^
(++) is expecting the right argument to be a:

    List (Maybe Char)

But the right argument is:

    Maybe (List Char)

Hint: I always figure out the type of the left argument first and if it is
acceptable on its own, I assume it is "correct" in subsequent checks. So the
problem may actually be in how the left and right arguments interact.

错误消息告诉我很多错误。不是 100% 确定我将如何修复它。列表连接运算符 ++ 期望 [Maybe Char] 而得到 Maybe [Char]


让我们尝试将字符串中的第一个字母大写(这不太酷,但实际上很现实)。

[String.toUpper ( List.head  x)] ++  (List.drop 1 x)

这是错误的,因为 Char.toUpper 需要 StringList.head xMaybe Char.

[Char.toUpper ( List.head  x)] ++  (List.drop 1 x)

这也是错误的,因为 Char.toUpper 需要 Char 而不是 Maybe Char

在现实生活中,用户可以通过输入非 Unicode 字符(如表情符号)来破坏这样的脚本。所以也许 Elm 的反馈是正确的。这应该是一个简单的问题,需要 "abcde" 并变成 "AbCdE"(或者可能 "aBcDe")。如何正确处理错误?

在 Elm 中,List.headList.tail 都是 return 它们 Maybe 类型,因为任一函数都可以传递无效值;具体来说,空列表。某些语言,如 Haskell,在将空列表传递给 headtail 时会抛出错误,但 Elm 会尝试尽可能多地消除运行时错误。

因此,如果您选择使用 headtail.

,则必须明确处理空列表的例外情况

注意:可能有更好的方法来实现字符串混合大写的最终目标,但我将重点关注 headtail 问题,因为它很好学习工具。

由于您使用的是连接运算符 ++,因此您需要一个用于两个参数的列表,因此可以肯定地说您可以创建几个函数来处理 Maybe return 值并将它们转换为一个空列表,这将允许您使用连接运算符。

myHead list =
  case List.head list of
    Just h -> [h]
    Nothing -> []

myTail list =
  case List.tail list of
    Just t -> t
    Nothing -> []

使用上面的 case 语句,您可以处理所有可能的结果并将它们映射到对您的情况有用的东西。现在您可以将 myHeadmyTail 交换到您的代码中,您应该已经准备就绪。