1

Haskell の初心者です。このプログラムについて助けが必要です。まず、3 つのアカウントを input.txt に保存します。ファイル内には ["1","steven","4000","12345"]["2","Marcus","5000" のようなものが含まれます。 ,"123456"]["3","Ivan","7000","12345"]アカウント内には、ID、名前、残高、パスワードの 3 つの変数があります。私がやりたいことは:

  1. ユーザーがパスワードを入力すると、プログラムはリスト内のパスワードをユーザーが入力したパスワードと比較し、最終的に特定のレコードを表示します

  2. ユーザーが他のユーザーに送金したい場合。最初に ID を挿入し、2 番目に金額を入力します。最後に、最初のアカウントで金額が減り、2 番目のアカウントで金額が増えます。

  3. 私が直面している問題は、比較、引き出し、送金するために単一のアカウントをどのように読み取ることができるかということです。それを行うより良い方法はありますか?

ありがとう

import System.IO  

i :: IO()
i = do
    putStrLn "your ID : " 
    id<-getLine
    putStrLn "your name : "
    name<-getLine
    putStrLn "balance : "
    bal<- getLine
    putStrLn "password : "
    pass<- getLine
    let store2 =  [id]++[name]++[bal]++[pass]
    appendFile "input.txt" (show store2)

huhu ::IO()
huhu = do
    putStrLn "ID : "
    id<-getLine
    putStrLn "Password : "
    pass<-getLine
    rec <- readFile "input.txt"
    if ("pass" == rec) then
        do
        putStrLn "show information"
    else
        do 
        putStrLn "Wrong password"
4

2 に答える 2

4

適切に構造化されたデータに直接飛び込むべきだと思います。まず、問題の解決に役立ついくつかのデータ型を定義します。

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.MapID を使用してアカウントを保存するか、リストを使用するかを決定する必要があります。リストはファイルから読み取る方が簡単ですが、マップは検索する方が簡単です。したがって、次のいずれかを行います。

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 の代わりにエラーが返されます。) 実行時エラーよりは良いかもしれませんが、今のところエラーを回避できるかもしれません。

一緒に接着する必要があり、次にファイルの入出力が必要です。ファイルの入出力については、使用するのが最も簡単readshowAccounts.

このようにする必要はありません。これは 1 つの方法にすぎません。(まあ、リスト対マップを 2 つのアプローチとして数えるなら、2 つです。) 楽しんでください!

于 2012-10-28T17:11:20.290 に答える
3

確かに、すべての問題は 3 番目の質問に要約されます。探しているのは、ユーザー名をユーザー アカウントにマップできるデータ構造です。Data.Mapコンテナの種類を見て、どのように使用できるかを確認することをお勧めします。

于 2012-10-28T14:09:26.760 に答える