0

独自の単語関数を作成する必要があります。文字列を取り、スペースがあればリストに入れます。たとえば、文字列 "i need help" は ["i","need","help"] になります。定義は正確でなければなりません

anything :: String -> [String]

私は現在、このような愚かな解決策を思いつきました(これも機能しません)

test :: String -> [String]
test d = beforep d : (test (afterp d)) : []

beforep :: String -> String
beforep d = takeWhile (/=' ') d
afterp :: String -> String
afterp d = if (dropWhile (/=' ') d)==[] then []
      else tail(dropWhile (/=' ') d)

テスト -> 末尾再帰を使用

beforep -> 最初のスペースまですべて取得

afterp -> スペースの後のすべてを取得します

何か案は ?この問題に対する他の解決策があれば、それが役立ちます。ありがとうございました

4

1 に答える 1

5

あなたはほとんどそれを手に入れました。コードをそのまま実行しようとすると、次のようになります。

test.hs:2:23:
    Couldn't match expected type `Char' with actual type `String'
    Expected type: String
      Actual type: [String]
    In the return type of a call of `test'
    In the first argument of `(:)', namely `(test (afterp d))'

2 行目を調べます。

test d = beforep d : (test (afterp d)) : []
--                                      ^
-- This is the problem -----------------|

cons 演算子の型は次のとおりです。

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

あなたのtest関数はすでにを返します[String]。それを空のリストにコンスしようとはしません。これは、戻り値の型が[[String]].

代わりにこれを試してください:

test d = beforep d : (test (afterp d))

その変更後、コンパイルされますが、実行test "i need help"すると無限リストが得られます。

["i","need","help","","","","","","","",""...

test問題は、空のリストを渡すと停止する基本ケースを含める必要があることです。作業コードは次のとおりです。

test :: String -> [String]
test [] = []
test d = beforep d : (test (afterp d))

beforep :: String -> String
beforep d = takeWhile (/=' ') d

afterp :: String -> String
afterp d = if (dropWhile (/=' ') d)==[]     -- Slightly reformatted
             then []                        -- to improve readability,
             else tail(dropWhile (/=' ') d) -- no real change.
于 2013-10-29T14:11:50.167 に答える