2017-01-19 6 views
0

特定の出力を生成しません。次の手順を実行して、この辞書にエントリ:入力値を識別することは、そのための機能は、私はこのような特定の入力文字列に応じて特定の文字列を出力する関数の形でデータ構造を構築し

addentry :: String -> String -> mydict -> mydict 
addentry s1 s2 d s 
| s1 == s = s2 
| otherwise = d s 

をs2の年代を探すために、私は単にS1入り、私の辞書に

looky :: String -> mydict -> String 
looky s1 d = d s1 --gives s2 
を見ることができます

私の目標は、特定のパターンで始まるs2と関連付けられているs1を確認できる別の関数patternmatchを作成することです。今ではパターンマッチング自体は問題ではありませんが、入力したエントリをどのように追跡することができないのですか?すなわち、どの入力が出力ではないのですか?"not found"

私の考えは、addentry関数に入力したすべてのs1を追跡し、それらを別のリストに追加することでした。 patternmatchでは、リストの要素をlookyに送ります。そうすれば、関連するs2を取得してパターンと一致するかどうかを確認できます。

だから私の質問:

1)このリストの建物のアプローチが良いですか機能が"not found"以外のものとして定義されている入力を特定する良い方法はありますか?

2)正しいアプローチであれば、どうすればs1を追跡できますか?

addentry s1 s2 d s 
| last (save s1) == s = s2 
| otherwise = d s1 

そしてsave s1すべてのS1の持つリストを生成する関数である:私のようなものを考えていました。 last (save s1)は、最新のs1を返します。 save s1やここからのその他の指示の実装についてのご意見をお待ちしております。どうもありがとう。

+1

あなたの教育的な練習を完了したら、あなたは[ 'Map'](HTTPに見たいかもしれません:/ /hackage.haskell.org/package/containers-0.5.9.1/docs/Data-Map-Lazy.html)、['TMap'](http://hackage.haskell.org/package/total-map-0.0 .6/docs/Data-TotalMap.html)を使って、「文字列を持たない」と「文字列を持っている」との区別をなくし、 '' not found ''にマップします。 –

答えて

1

あなたのデザインは、キーを見つけるための唯一の基準が同じ正確なキーを提示することであるようにハードコードされています。あなたが必要とするものは、平等以外の基準を提供するより柔軟なアプローチです。私はあなたのコードは、より一般的な作りと機能のためのより多くの従来の名前を使用しての自由を取った:

import Prelude hiding (lookup) 

-- instead of k -> Maybe v, we represent the dictionary as 
-- (k -> Bool) -> Maybe v where k -> Bool is the criteria 
-- on which to match the key. by using Maybe v we can signal 
-- that no qualifying key was found by returning Nothing 
-- instead of "not found" 
newtype Dict k v = Dict ((k -> Bool) -> Maybe v) 

empty :: Dict k v 
empty = Dict $ const Nothing 

-- insert a new key/value pair 
insert :: k -> v -> Dict k v -> Dict k v 
insert k v d = Dict $ \f -> if f k then Just v else lookupBy f d 

-- lookup using the given criteria 
lookupBy :: (k -> Bool) -> Dict k v -> Maybe v 
lookupBy f (Dict d) = d f 

-- lookup using the default criteria (equality with some given key) 
lookup :: Eq k => k -> Dict k v -> Maybe v 
lookup k = lookupBy (k==) 

-- your criteria 
startsWith :: String -> String -> Bool 
startsWith s = undefined -- TODO 

lookupByPrefix :: String -> Dict String v -> Maybe v 
lookupByPrefix = lookupBy . startsWith 

私は、これは関数型プログラミングの実践と一般的な脳の拡張のための偉大な運動ですが、それはひどいやり方だと言及する必要がありますマップを実装する。ペアのリストは同等で分かりやすくなります。

注意点として、私たちは簡単にこのタイプのFunctorのインスタンスを定義することができますが:

instance Functor (Dict k) where 
    fmap f d = Dict $ \g -> fmap f (lookupBy g d) 
+1

'singleton'はここで使う奇妙なプリミティブのようです。代わりに 'empty = Dict $ const Nothing'を定義し、その上に' insert'を呼び出すのはどうですか?これは、 'insert'と' singleton'の間の重複を避けます。 – amalloy

+0

ニース!私は、多くのキーが述語を満たすので、 'Dict((k - > Bool) - > [v])'を使うことも誘惑されるでしょう。これにより、 'someDict(const True)'としてサポートセットを回復することが可能になります。 (もちろん、キーを挿入/削除すると、遅くて遅い辞書につながりますが、実際のマップはまだまだ良いでしょう) – chi

+0

@amalloy良い提案です。私は自分の投稿を更新しました – user2297560

関連する問題