如何大写字符串的第一个字母,并在Haskell中小写其余字母

时间:2013-11-20 10:27:03

标签: string haskell

我必须编写一个函数,该函数大写字符串的FIRST字母,并且LOWERCASE字符串的其余部分(此字符串包含随机的大写字母或小写字母)。

到目前为止,我已设法做到了这一点:

capitalised :: String->String
capitalised [] = []
capitalised x
            | length x == 1 = map toUpper x
            | otherwise = capitalised (init x): map toLower (last x)

和所有其他奇怪的功能,我仍然无法弄明白。

请帮忙! Tx提前!

忘了提,问题是我需要写一个递归的解决方案!

5 个答案:

答案 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.Conseach来自Control.Lens.Eachover来自Control.Lens.Setter

这个定义的好处在于它应该与SeqVectorTextString之外的其他数据类型一起使用,因为它们都是{{的实例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)

只使用headtail,而不是initlast

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]

认为这是初学者可以使用的最递归的答案:)