我过去的一两个下午都在盯着我的电脑,好像我以前从未见过一样。今天的主题列表
练习是取一个字符串并将所有其他字母大写。我没有走得太远......
我们来一个列表x = String.toList "abcde"
并尝试分析它。如果我们添加take 1
和drop 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
我认为head
和tail
做了同样的事情,但我收到了一条很大的错误信息:
> [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
需要 String
,而List.head x
是 Maybe Char
。
[Char.toUpper ( List.head x)] ++ (List.drop 1 x)
这也是错误的,因为Char.toUpper
需要 Char
而不是 Maybe Char
。
在现实生活中,用户可以通过键入非Unicode字符(如表情符号)来破坏这样的脚本。也许Elm的反馈是正确的。这应该是一个简单的问题,它需要“abcde”并变成“AbCdE”(或可能是“aBcDe”)。如何正确处理错误?
答案 0 :(得分:1)
在Elm中,List.head
和List.tail
都返回Maybe
类型,因为任一函数都可以传递无效值;具体来说,空列表。某些语言(如Haskell)在将空列表传递给head
或tail
时会抛出错误,但Elm尝试尽可能多地消除运行时错误。
因此,如果您选择使用head
或tail
,则必须明确处理空列表的例外情况。
注意:可能有更好的方法来实现字符串混合大写的最终目标,但我会关注head
和tail
问题,因为它是一个很好的学习工具。< / em>的
由于您正在使用连接运算符++
,因此您需要为两个参数都使用List,因此可以肯定地说您可以创建一些处理Maybe
返回值的函数和将它们转换为空列表,这将允许您使用连接运算符。
myHead list =
case List.head list of
Just h -> [h]
Nothing -> []
myTail list =
case List.tail list of
Just t -> t
Nothing -> []
使用上面的case
语句,您可以处理所有可能的结果,并将它们映射到可用于您的环境的内容。现在,您可以将myHead
和myTail
交换到您的代码中,您应该全部设置。