2017-11-07 19 views
1

私はハスケルを学び、現在再帰的な "辞書"または "トランスレータ"関数を作成しようとしています。 基本的には、タプルやスティングの配列のようなスティッキングの配列を受け取って、最初のものと一致する場合はタプルの2番目の部分で置き換えられた要素の文字列を返します。 そこで、基本的ハスケル再帰的辞書関数の問題

["a", "b", "zz"] [("a", "11"),("b","c")] 

から

["11","c","zz"] 

に悩み、それは...これは私がこれまで持っているものである作る持つ:

aa (x:xs) (y:ys) = do 
    -- iterate through y 
    if ys == [] then return(x:xs) else aa (x:xs)(ys) 
     -- iterate through x 
    if xs == [] then return(x:xs) else aa (xs)(y:ys); 

    if x == fst(y) 
    then do 
     putStrLn("Yes"); 
     return (snd(y):xs); 
    else return (x:xs); 

配列の第一の要素のために働きました。 私はそれをどのように通過させるかを理解できないようです。 putStrLnを削除すると、エラー "不一致"が発生します。なぜですか?

それを理解しようとしながらも、結果を格納しようとした、それがうまくいかなかった:

aa (x:xs) (y:ys) = do 

    if x == fst(y) 
    then result <- snd(y):xs 
    else result <- x:xs 

    return result; 

がエラーになった「パースエラーを入力 『< - 』におそらくこれは、にする必要があります'do'ブロック? "

+0

一致するものが見つかると、もう一度繰り返すことはありません(コールaa)。また、はるかに簡単な実装は、タプルの配列をキーとしてfst()、値としてsnd()として辞書に入れます。次に、リストを繰り返します(これは再帰的でも非再帰的でも構いません)foreach要素であり、辞書内のそのキーの値を返します。そうでなければリスト内の値を返します(dict.getOrDefault(element、element)) – tpdi

+0

'ys == []'が* whole *リストが空であるかどうかを調べてはいけません。あなたのコードは機能的ではなく不可欠であると言われています。そしておそらく、辞書の* single *値を調べることができる関数を書くことで、あなた自身がもっと楽になるはずです。 –

+0

また、 'return'と' do'をたくさん使います。これらは 'Monad'関数です。通常、これらは純粋な関数では頻繁に見つかりません。 –

答えて

3

これを分解すると、これは解決するのが難しい問題ではありません。まず、タプルとキーのリストを取得し、そのキーの値がリストに存在する場合はそれを返す関数が必要です。

幸いこれは、すでにそれはたぶん、値を返しますlookup

で、私たちのために定義されています。見つからなければ元の値に戻すことができます。 fromMaybeこれは私たちのためにこれを行います、それはデフォルト値と多分値をとり、多分値がちょうどあれば、ちょうどの値を返します。

これで、リストの上にマップするだけで、各アイテムについて、アソシエーションリストのアイテムがあればそれがアソシエーションリストに置き換えられます(存在しない場合)。

そして、ここではコードです:

import Data.Maybe (fromMaybe) 

translator xs ys = map replace xs 
    where replace x = fromMaybe x (lookup x ys) 

あなたのコードは、あなたが表示されるという点でいくつかの問題は、それが本当に必要いないときの表記を行う使用しようとする必要があります。あなたが初心者のときは、IOを使う関数でdo notationを使うだけです。すべてを1つの長いステートメントにしないように定義する場合は、whereまたはletを使用できます。

λ> translator ["a", "b", "zz"] [("a", "11"),("b","c")] 
["11","c","zz"] 
λ>