3

我正在玩这个lens包,我试图只使用镜头来大写一个字符串。基本上我想调用toUpper每个单词的每个第一个元素。这似乎很容易做到,但我根本不知道该怎么做。我需要一个可遍历的吗?我如何按空格等分割...

4

3 回答 3

4

调用wordsthen并不是真正的同构,unwords因为它会将重复的空格转换为单个空格,但让我们假设:

words :: Iso' String [String]
words = iso Prelude.words Prelude.unwords

现在我们可以通过构建一个专注于每个单词的第一个字母并应用over和应用的镜头来大写单词toUpper

capitalize :: String -> String
capitalize = over (words . traverse . _head) toUpper
于 2014-07-09T12:31:28.773 回答
3
capitalize xs = xs & words <&> _head %~ toUpper & unwords

好的,这就是解决方案,但是如何到达那里?让我们移除一些镜头部件。(<&>)fmap和交换:(&)_($)

capitalize xs = unwords $ fmap (_head %~ toUpper) $ words $ xs

这看起来很熟悉。_head %~ f将应用于f列表的第一个元素。最后,这(几乎*)相当于

capitalize xs = unwords $ fmap (\(x:xs) -> toUpper x : xs) $ words $ xs

您可能很熟悉。


*_head也处理空列表的情况

于 2014-07-09T12:05:00.230 回答
3

不折叠重复空格的解决方案:

import Control.Lens
import Data.List.Split
import Data.List.Split.Lens
import Data.Char

capitalize :: String -> String
capitalize = view $ splitting (whenElt isSpace) traversed.to (over _head toUpper)
于 2014-07-09T15:19:45.877 回答