文字列を展開する関数を書いています
例:
foo "a4b4"
返す必要があります:
"aaaabbbb"
これが私のコードです:
foo :: String -> String
foo (x:xs) = let curent = fooHelp(x, read $ charToString( xs !! 0 ) :: Int)
in x : (curent) ++ foo (tail xs)
fooHelp:
fooHelp :: String -> Int -> String
fooHelp x n
| n >= 3 = x ++ fooHelp x (n - 1)
| n == 2 = x
| n == 1 = ""
およびcharToString:
charToString :: Char -> String
charToString c = [c]
xを取り、それを現在の値に追加します。現在のfooHelpでは、展開された文字列が返されます
例は:foo "a4b4"
その後x = "a"
、xs = "4b4"
、xs !! 0 = '4'
read $ charToString( xs !! 0 ) :: Int)
文字を変換します'4'
intに4
し、Xと一緒fooHelpにそれを渡す(「」) - >fooHelp(x, 4)
と「AAA」をお返し。その後、x : current
戻って与えるべきで"aaaa"
あるためx = "a"
、現在"aaa"
で、次いで再帰呼び出し++ foo tail xs
ところxs ="b4"
、それはプロセスを繰り返す必要があります。
エラーが発生します:
test.hs:173:34: error:
• Couldn't match type ‘(Char, Int)’ with ‘[Char]’
Expected type: String
Actual type: (Char, Int)
• In the first argument of ‘fooHelp’, namely
‘(x, read $ charToString (xs !! 0) :: Int)’
In the expression:
fooHelp (x, read $ charToString (xs !! 0) :: Int)
In an equation for ‘curent’:
curent = fooHelp (x, read $ charToString (xs !! 0) :: Int)
|
173 | foo (x:xs) = let curent = fooHelp(x, read $ charToString( xs !! 0 ) :: Int)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
どこで間違えたの?関数fooHelpをテストしましたが、fooのような引数で正常に動作します。
fooHelpのテスト:
xs = "4b4"
test = read $ charToString( xs !!0 ) :: Int
*Main> test
4
古典的な間違いは、のような関数を呼び出すことf (x1, x2)
です。Haskellでは、関数には1つのパラメーターがあり、多くの場合、これはタプルではありません。
あなたのfooHelper
関数はタイプがあります。
fooHelp :: String -> (Int -> String)
したがって、これはString
を受け取る関数であり、Int
sをString
sにマップする関数を返します。したがって、次のような関数を呼び出す必要があります。
(fooHelp x) (read $ charToString( xs !! 0 ) :: Int)
以下の冗長性:
(fooHelp x) (read $ charToString( xs !! 0 ) :: Int)
しかし、今でも型は一致していません:x
は、Char
ではなくString
、次のようにリストでラップできます。
fooHelp [x] (read $ charToString( xs !! 0 ) :: Int)
お気に入り:
foo :: String -> String
foo (x:xs) = let curent = fooHelp [x] (read $ charToString( xs !! 0 ) :: Int)
in x : (curent) ++ foo (tail xs)
しかし、それでもこの関数には問題があります。文字列を反復処理するため、最終的には空の文字列に到達し、foo
その場合はありません。その場合、次のように空の文字列を返す必要があります。
foo :: String -> String
foo (x:xs) = let curent = fooHelp [x] (read $ charToString( xs !! 0 ) :: Int)
in x : (curent) ++ foo (tail xs)
foo [] = ""
しかし、それはまだあまりエレガントではありません。ここでは、文字を文字列にラップするなど、多くの不要な操作を実行します。
このreplicate :: Int -> a -> [a]
関数を使用して、文字を指定された回数繰り返すことができます。例えば:
Prelude> replicate 3 'a'
"aaa"
さらに、このdigitToInt :: Char -> Int
関数は、対応するInt
:に数字を解析できます。
Prelude Data.Char> digitToInt '3'
3
したがって、ここでは、これら2つを使用replicate (digitToInt k) x
して、文字列の最初の2文字を取得し、x
siが要求された時間を繰り返した文字列を生成し、次のように文字列の残りの部分で再帰を実行できます。
import Data.Char(digitToInt)
foo :: String -> String
foo (x:k:xs) = replicate (digitToInt k) x ++ foo xs
foo _ = ""
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加