如何使用控制镜头大写字符串?

时间:2014-07-09 11:33:53

标签: haskell lens

我正在使用lens包,我正在尝试仅使用镜头来大写字符串。 基本上我想在每个单词的每个第一个元素上调用toUpper。这似乎很容易,但我根本无法弄清楚如何做到这一点。我需要一个可穿越的吗?我如何按空格等分割......

3 个答案:

答案 0 :(得分:4)

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

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

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

capitalize :: String -> String
capitalize = over (words . traverse . _head) toUpper

答案 1 :(得分: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也会处理空列表案例

答案 2 :(得分: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)