2017-08-27 11 views
-2

私はHaskellにとってはかなり新しいです。私は、2つの値とリストを取り、リストの最初の値のすべてのインスタンスを2番目の値に置き換えるプログラムを作成しようとしています。例えば。 repOcc 'n' 'i' "pink""piik"を返します。Haskellリストの値を別の値に置き換えてください。

次は私のコードです:

repOcc :: t -> t -> [t] -> [t] 
repOcc x y (z:zs) = if z == x 
         then z = y 
         subst x y zs 
         else subst x y zs 

私は、コンパイル時に受けていますエラーは次のとおりです。Haskellは「よりなることを目指してのに対し、あなたのプログラムではなく、「不可欠」を探します

rev.hs:3 :32: error: 
    parse error on input '=' 
    Perhaps you need a 'let' in a 'do' block? 
    e.g. 'let x = 5' instead of 'x = 5' 
Failed, modules loaded: none. 
+1

をコードは、あなたの期待から外れた方法を明記してください。コンパイラエラーはありますか?そのエラーは何ですか?プログラムが間違った出力をしていますか?入力と誤った出力の例は何ですか? – erisco

+0

より簡単に開始: 'f from to x'関数を書くことができます。' f'は 'x'が' from'と等しく、 'x'が変更されていなければ' to'と評価されます。 – Ryan

+0

コンパイル時に解析エラーが発生しました。コンパイラが 'doブロック'に 'let'を追加するように指示しています – RNee

答えて

3

宣言的 "。したがって、リスト内に変数zを設定することはできません。リストが構築されると、それ以上は変更できません。したがって、xに等しい要素がyに設定されている新しいリストを作成する必要があります。

次に、(==)機能を使用します。その関数はEq型クラスで定義されているため、型制約としてEq tを署名に追加する必要があります。

これで、このような機能を構築することができます。通常、リストを操作するときは、再帰を使用します。再帰の基本ケースは、通常、空のリストです。空のリストに遭遇した場合、xyに関係なく、空のリストを返さなければなりません。

repOcc _ _ [] = [] 

再帰的な場合があるリストが頭hとで尾tが含まれている場合:だから我々は、パターン「を気にしない」、およびリストパターンとして[]を使用し、書き込みとしてアンダースコアを使用します(h:t)パターン。その場合、hxと等しいかどうかをチェックします。その場合は、yを先頭にしてリストを作成します。それ以外の場合はhがまだ頭です。

repOcc x y (h:t) | x == h = y : tl 
       | otherwise = h : tl 

今の質問は、結果リストtlの尾がどうあるべきかのまま。ここでは、再帰を使用するので、私たちはrepOccx y tを呼び出す:

where tl = repOcc x y t 

または一緒にそれを置く:

repOcc :: Eq t => t -> t -> [t] -> [t] 
repOcc _ _ [] = [] 
repOcc x y (h:t) | x == h = y : tl 
       | otherwise = h : tl 
    where tl = repOcc x y t 

を私たちは、このような再帰関数を書くことができますが、上記実際にmap機能の特殊なケースであります:すべての文字をxと等しいかどうかをチェックするようにマッピングし、そうであればyを返します。それ以外の場合はhを返します。だから我々は、上記のように書き換えることができます:私たちはさらにETA -reductionを利用して、コードを向上させることができます

repOcc :: Eq t => t -> t -> [t] -> [t] 
repOcc x y ls = map (\h -> if h == x then y else h) ls 

repOcc :: Eq t => t -> t -> [t] -> [t] 
repOcc x y = map (\h -> if h == x then y else h) 
関連する問題