2017-12-23 27 views
-1

文字列を読み込み、その中に保存されている文字列から単語を含むリストを返すHaskell関数を記述しようとしています。文字列からリストへの単語

は、ここで私はそれをやった方法は次のとおりです。

toWordList :: String -> [String] 
toWordList = do 
[ toLower x | x <- str ] 
    let var = removePunctuation(x) 
     return (words var) 

しかし、私はこのエラーを取得する:

Test1.hs:13:17: error: parse error on input 'let' 
    | 
13 |     let var = removePunctuation(x) 
    |     ^^^ 

私はHaskellのに新たなんだので、私は感謝してその構文上で把握していません助けを求めて進んでください。

答えて

1

ここにはかなりの間違いがあります。チュートリアル(learn you a HaskellReal World Haskell)を読んでもっと多くの時間を費やす必要があります。あなたはかなり近くにいるので、私はここでブレークダウンをしようとします。

doは特別である - それは「不可欠モード」にはHaskellを切り替えていない、それはモナドを使用するときに明確なコードを書くことができます - あなたがまだあるかモナドわからない場合は、離れてdoから滞在します! returnなどのキーワードも、命令的言語と同じように動作しません。完全に新鮮な心でハスケルにアプローチしよう。

また、ハスケルでは、インデントが重要です。詳しくは、this linkを参照してください。基本的に、同じ "ブロック"内のすべての行に同じ字下げを付ける必要があります。


さて、doreturnキーワードを取り除くみましょう、とインデントを揃えます。また、パラメータの名前をstrにします。元のコードでは、このビットを間違えていました。 letため

toWordList :: String -> [String] 
toWordList str = 
    [toLower x | x <- str] 
    let var = removePunctuation(x) 
    words var 

構文はlet __ = __ in __です。 doを使用するときには別の表記法がありますが、今のところそれを忘れてしまいます。リストの理解の結果に名前を付けていないので、それをやりましょう:

toWordList str = 
    let lowered = [toLower x | x <- str] in 
    let var = removePunctuation lowered in 
    words var 

これは機能します。私たちは文法を正しく取得し、モナディックな構文的砂糖(do/return)を避ける必要がありました。


でも、それはよりうれしいです。それらのletブロックはちょっと醜いです、私たちはそれらを取り除くことができます。我々はまた、もう少しエレガントであり、あなたの理解に相当しmap toLowerとリスト内包、置き換えることができます。

toWordList str = words (removePunctuation (map toLower str)) 

ニース、それが今、単一の行までです!しかし、それらのすべての括弧も少し目障りです。私たちはどうすればthe $ functionを使用しますか?

toWordList str = words $ removePunctuation $ map toLower str 

良い。これを別の改善があります。これはpoint-free styleに変換されます。ここではパラメータを明示的に指定しません。代わりにこの関数を他の関数の構成として表現します。

toWordList = words . removePunctuation . (map toLower) 

そして、我々は完了です。うまくいけば、最初の2つのコードスニペットは、Haskellの構文がどのように動作するかを明確にし、最後のほんのいくつかは、かなり冗長なコードをどのようにしてもっときれいにすることができるかの良い例を示すかもしれません。

関連する問題