適切に構造化されたデータに直接飛び込むべきだと思います。まず、問題の解決に役立ついくつかのデータ型を定義します。
type ID = Int
data Account = Account {idno::ID,
name :: String,
balance :: Int,
password :: String} deriving (Read,Show)
必要に応じて、さまざまなタイプを選択できます。これにより、次のような関数を定義できます
sameID :: ID -> Account -> Bool
sameID anID account = idno account == anID
データ ラベルidno
も便利な関数であることに注目してくださいAccount -> ID
。テストにはいくつかのサンプル データを使用する必要があります。
sampleData = [Account 385634 "Fred" 234 "Iluvw1lm4",
Account 405382 "Barney" (-23) "pebbles",
Account 453464 "Wilma" 1432 "c4r3fu1n355 br33d5 pr0sp3r:ty"]
これを使用して機能をテストできます (そして、Barney はパスワードのセキュリティや財務管理についてまったく手がかりがないと推測できます)。
Data.Map
ID を使用してアカウントを保存するか、リストを使用するかを決定する必要があります。リストはファイルから読み取る方が簡単ですが、マップは検索する方が簡単です。したがって、次のいずれかを行います。
type Accounts = [Account]
またはマップを使用します。
import qualified Data.Map as Map -- Put this at the top of the file if so.
type Accounts = Map.Map ID Account
いずれにせよ、必要になります
findUserByID :: Accounts -> ID -> Maybe Account
findUserByID = undefined -- you can work this out
マップを使用している場合は、マップを見つける必要があります。ドキュメントを参照するか (いずれにせよ適切な計画です)、またはhoogle 検索エンジンを使用してドキュメントを見つけてください。よくわからない場合はMap ID Account -> Maybe Account
、ID やアカウントがわからないという警告が表示されますが、必要な機能はそこにあります。Map id account -> Maybe account
一般的な機能を使用できることを認識できるように、検索する方がよいでしょう。
filter
リストを使用している場合は、ID が一致する場合は true を返し、そうでない場合は false を返す関数をリストに追加する必要がありsameID
ます。
また、必要になります
updateByID :: ID -> Account -> Accounts -> Accounts
updateByID anId newaccount = undefined -- you can work this out too
しかし、はるかに便利になります
updateUsingID :: Account -> Accounts -> Accounts
updateUsingID acc = updateByID (idno acc) acc
マップを使用している場合は簡単ですが、リストを使用している場合は、次map
のような関数にする必要があります
onlyChange :: Account -> (Account -> Account)
onlyChange newacc acc | idno acc == idno newacc = newacc
| otherwise = acc
定義できます
showAccount :: Account -> String
showAccount acc = undefined -- use the functions, eg name acc ++ ....
-- or just use show
そして次のような機能
changePassword :: String -> Account -> Account
changePassword newpwd acc = acc {password = newpwd}
のアイデアchangePassword
と functionを使用すると、次のbalance
ように記述できるはずです。
changeBalance :: (Int -> Int) -> Account -> Account
changeBalance = undefined -- you try
それからあなたは書くことができます
pay :: Int -> Account -> Account -> (Account,Account)
pay amount fromAcc toAcc = undefined
ヒント: と を使用changeBalance (+ amount)
しchangeBalance (subtract amount)
ます。
最後に必要になります
updateTwoUsingID :: (Account,Account) -> Accounts -> Accounts
updateTwoUsingID (new1,new2) = updateUsingID new1 . updateUsingID new2
これは関数合成の素敵な例なので、言わずにはいられませんでした。
Maybe Account
ファイル IO を最後まで無視するのと同じように、それらを使用するのが難しい場合は、最後まで無視してください。fmap
やのような関数は、>>=
を使用するときに便利Maybe
です。それらを調べるか、今のところ Maybe を完全に捨てて hard を使用してerror
ください。(たとえば!
、Map では Nothing の代わりにエラーが返されます。) 実行時エラーよりは良いかもしれませんが、今のところエラーを回避できるかもしれません。
一緒に接着する必要があり、次にファイルの入出力が必要です。ファイルの入出力については、使用するのが最も簡単read
でshow
、Accounts
.
このようにする必要はありません。これは 1 つの方法にすぎません。(まあ、リスト対マップを 2 つのアプローチとして数えるなら、2 つです。) 楽しんでください!