我必须编写一个函数,该函数大写字符串的FIRST字母,并且LOWERCASE字符串的其余部分(此字符串包含随机的大写字母或小写字母)。
到目前为止,我已设法做到了这一点:
capitalised :: String->String
capitalised [] = []
capitalised x
| length x == 1 = map toUpper x
| otherwise = capitalised (init x): map toLower (last x)
和所有其他奇怪的功能,我仍然无法弄明白。
请帮忙! Tx提前!
忘了提,问题是我需要写一个递归的解决方案!
答案 0 :(得分:19)
请记住,String
只是[Char]
的类型同义词?在这里我们利用它:
import qualified Data.Char as Char
capitalized :: String -> String
capitalized (head:tail) = Char.toUpper head : map Char.toLower tail
capitalized [] = []
这是一个递归版本:
capitalized :: String -> String
capitalized [] = []
capitalized (head:tail) = Char.toUpper head : lowered tail
where
lowered [] = []
lowered (head:tail) = Char.toLower head : lowered tail
答案 1 :(得分:9)
警告:此解决方案可能过度,而不是新手,但是这里是如何使用lens
包中的遍历来实现的。
import Control.Lens
import Data.Char
capitalize :: *really scary type would go here*
capitalize = over _head toUpper . over (_tail.each) toLower
_head
和_tail
来自Control.Lens.Cons
,each
来自Control.Lens.Each
,over
来自Control.Lens.Setter
。
这个定义的好处在于它应该与Seq
,Vector
,Text
和String
之外的其他数据类型一起使用,因为它们都是{{的实例3}}和Cons。例如:
import qualified Data.Text as T
import qualified Data.Sequence as S
over _head toUpper . over (_tail.each) toLower $ "aA"
-- "Aa"
over _head toUpper . over (_tail.each) toLower $ T.pack "aA"
-- "Aa"
over _head toUpper . over (_tail.each) toLower $ S.fromList "aA"
-- "Aa"
编辑:这是另一种方法,只是为了它的地狱。
import Data.Char
import Control.Lens
import Control.Arrow (***)
over _Cons (toUpper *** over each toLower) "aA"
答案 2 :(得分:0)
你在网上有错误:
| otherwise = capitalised (init x): map toLower (last x)
只使用head
和tail
,而不是init
和last
:
capitalised [] = []
capitalised x =
| length x == 1 = map toUpper x
| otherwise = head (capitalised [head x]) : map toLower (tail x)
此解决方案不是最佳选择。尼基塔沃尔科夫的版本更漂亮。 或者我们可以将其重写为
capitalised [] = []
capitalised x = toUpper (head x) : map toLower (tail x)
答案 3 :(得分:0)
在各种库的帮助下,结合使用更多的方法来实现此目的:
Prelude> :m +Data.Char Data.List
> let ucfirst x = (toUpper $ head x) : (toLower <$> tail x)
Prelude> :m +Data.Char Data.List Control.Arrow
> let ucfirst = (head >>> toUpper) &&& (tail >>> (toLower <$>)) >>> uncurry (:)
Prelude> :m +Data.Char Data.List Control.Applicative
> let ucfirst = liftA2 (:) (toUpper . head) ((toLower <$>) . tail)
他们都做同样的事情:
> ucfirst "fOO"
"Foo"
答案 4 :(得分:0)
来到这里是因为我必须回答同样的问题,并提出了解决方案
capitalised [] = []
capitalised xs | length xs == 1 = capitalised (init xs) ++ [toUpper c | c<-xs]
| otherwise = capitalised (init xs) ++ [toLower c | c<-xs, c == last xs]
认为这是初学者可以使用的最递归的答案:)