我正在玩这个lens
包,我试图只使用镜头来大写一个字符串。基本上我想调用toUpper
每个单词的每个第一个元素。这似乎很容易做到,但我根本不知道该怎么做。我需要一个可遍历的吗?我如何按空格等分割...
问问题
242 次
3 回答
4
调用words
then并不是真正的同构,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 回答