私はコンピュータープログラムの構造と解釈に取り組んでおり、Haskell の演習を完了しています。最初の 2 つの章は問題ありませんでしたが (コードはgithubにあります)、第 3 章ではさらに難しく考えさせられます。
まず、銀行口座を例に、状態の管理について説明します。make-withdraw
関数を次のように定義します。
(define (make-withdraw balance)
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds")))
次のコードを実行できるようにします。
(define w1 (make-withdraw 100))
(define w2 (make-withdraw 100))
(w1 50)
50
(w2 70)
30
(w2 40)
"Insufficient funds"
(w1 40)
10
Haskell でこれをエミュレートする方法がわかりません。私は最初に State モナドを使ったいくつかの単純な関数を考えました:
import Control.Monad.State
type Cash = Float
type Account = State Cash
withdraw :: Cash -> Account (Either String Cash)
withdraw amount = state makewithdrawal where
makewithdrawal balance = if balance >= amount
then (Right amount, balance - amount)
else (Left "Insufficient funds", balance)
これにより、コードを実行できます
ghci> runState (do { withdraw 50; withdraw 40 }) 100
(Left "Insufficient funds",30.0)
しかし、それはスキームコードとは異なることをします。理想的には、次のようなものを実行できます
do
w1 <- makeWithdraw 100
w2 <- makeWithdraw 100
x1 <- w1 50
y1 <- w2 70
y2 <- w2 40
x2 <- w1 40
return [x1,y1,y2,x2]
[Right 50,Right 70,Left "Insufficient funds",Right 40]
しかし、関数の書き方がわかりませんmakeWithdraw
。何かアドバイス?