我一直在研究计算机程序的结构和解释,并在 Haskell 中完成练习。前两章很好(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 monad 的简单函数:
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
。有什么建议吗?