0

そうでない場合は、文字列の最初の文字を作成したい。これは私がやっていることです:

import Data.Char

onlyCapitals :: [String] -> [String]
onlyCapitals [] = []
onlyCapitals (x:xs) = if isUpper $ head x 
                      then x ++ onlyCapitals xs  -- 1
                      else toUpper (head x) : tail x ++ onlyCapitals xs -- 2 and 3

main = print $ onlyCapitals ["Aaaa", "bbb", "ffff"]

そして、3つのエラーが発生しました:

Couldn't match type `Char' with `[Char]'
    Expected type: [String]
      Actual type: String

Couldn't match type `Char' with `[Char]'
    Expected type: String
      Actual type: Char

Couldn't match type `Char' with `[Char]'
    Expected type: [String]
      Actual type: String
4

2 に答える 2

4

まず気づくこと

(++) :: [a] -> [a] -> [a]
(:)  :: a -> [a] -> [a]

String ++ [String]したがって、最初のエラーは、型エラーであるようなことをしようとすることです。代わりに、(:)

次の問題は

toUpper (head x) : tail x ++ onlyCapitals xs

問題は、 と の結合性と優先順位++:どちらも右に同じレベルであることです。したがって、これは次のように解析されます

toUpper (head x) : (tail x ++ onlyCapitals xs)

これは、明示的な括弧で修正され、再び切り替え++られます:

(toUpper (head x) : tail x) : onlyCapitals xs

スタイルノート

これで動作しますが、空の文字列を渡すとクラッシュします。代わりに、おそらくこのようなものがより良いでしょう

onlyCapitals :: [String] -> [String]
onlyCapitals = map cap
  where cap "" = ""
        cap (x : xs) = toUpper x : xs

リストの明示的な再帰と構築を抽象化し、単に に任せmapます。次に、空でない文字列の最初の文字を適切に処理""して大文字にします。

于 2013-11-03T15:40:00.467 に答える