Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何使用控制镜头将字符串大写?_Haskell_Haskell Lens - Fatal编程技术网

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

Haskell 如何使用控制镜头将字符串大写?,haskell,haskell-lens,Haskell,Haskell Lens,我正在玩lens软件包,我试图只用lens将字符串大写。 基本上,我想对每个单词的第一个元素调用toUpper。这看起来很容易,但我根本不知道怎么做。我需要一个可遍历的吗?如何按空格等分割 capitalize xs = xs & words <&> _head %~ toUpper & unwords 这看起来是家喻户晓的\u head%~f将在列表的第一个元素上应用f。最后,这(几乎*)相当于 capitalize xs = unwords $ fmap

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

capitalize xs = xs & words <&> _head %~ toUpper & unwords
这看起来是家喻户晓的
\u head%~f
将在列表的第一个元素上应用
f
。最后,这(几乎*)相当于

capitalize xs = unwords $ fmap (\(x:xs) -> toUpper x : xs) $ words $ xs
你可能很熟悉



*
\u head
还负责空列表大小写

调用
单词
然后
取消单词
实际上不是同构,因为它会将重复的空格转换为单个空格,但让我们假装:

words :: Iso' String [String]
words = iso Prelude.words Prelude.unwords
现在我们可以通过构建一个聚焦于每个单词的第一个字母的透镜,并在和上应用
touper来大写单词

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

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

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)

如果你愿意考虑<代码>(单词,unWord)< /代码>一个同构,那么你可以通过一个对<>代码>( > .j.abrHAMSON的单次调用来完成这一切:谢谢你的额外回答。这实际上是我第一次使用镜头。使用
Iso
的技巧非常棒。然而,我应该后退几步,阅读更多关于Traversable的内容,我完全忘记了
traverse
,花了太多时间寻找一个操作符(我最终得到了
over\uWords$fmap(\u head%~touper)
)我很高兴把单词和unWord看作同构,因为它只是一个穿越同构的例子。这就是我要找的。我正在ghci中尝试
让w=isowords unwords::iso'String[String]
,我得到以下错误:
没有(Profunctor p0)的实例。
。有什么想法吗?嗯。现在我必须实际安装
lens
。我将在大约20分钟后回复。@mb14将类型签名放在自己的行上。如果您首先运行
:set+m
,您将在GHCi中获得多行输入。这个问题是由于GHC的类型推断是如何处理独立类型签名的。inline@mb14或者,运行
:set-XNoMonomorphismRestriction
,让GHCi按照您期望的方式解释它。
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)