gpt4 book ai didi

haskell - 基于列表制作我自己的一元类型

转载 作者:行者123 更新时间:2023-12-02 20:53:58 26 4
gpt4 key购买 nike

我想使用 Haskell 来解决金融组合问题,列表 monad 似乎很适合这个问题。

现在,我对列表 monad 的问题是它无法为所涉及的值命名。我将尝试举例说明:

loan = [1000*x | x <- [1..3]]
interest_rate = [0.005*x | x <- [4..10]]

calc = do
l <- loan
i <- interest_rate
return (l*i)

运行上面的 calc 会给出一个数字列表 ([20.0,25.0,30.0,35.0,40.0, ... ]),但我无法判断贷款和利率是多少用于每次计算。

我在这里迷失了方向,我的直觉告诉我创建自己的一元类型,例如 HelpfulNumber::(String,[Double]) 并以某种方式说:

>>=return 应该是 >>= 。 sndreturn 。 snd

我的做法正确吗,还是有更好的方法?说实话,我感觉有点失落。

最佳答案

您可以使用记录类型使输出更清晰:

data Loan = Loan {final :: Double, 
rate :: Double,
loan :: Integer,
years :: Int}
deriving Show

printloans :: [Loan] -> IO()
printloans = mapM_ print

使用printloans loansprintloans loans'在 ghci 提示符下。

编辑:我忘记包含 dp 的定义。它用于四舍五入到给定的小数位数:

dp :: Int -> Double -> Double
n `dp` a = (/ 10.0^n).fromInteger.round.(* 10.0^n) $ a

这是直接使用列表的方法:

loans = [Loan {final = (2 `dp`) $ fromInteger amt*(1+ir)^yrs, 
rate = ir,
loan = amt,
years = yrs}
| ir <- [0.005*x | x <- [4..10]],
amt <- [1000*x | x <- [1..3]],
yrs <- [1..4]
]

但是如果你喜欢一元风格,你可以使用:

loans' = do
ir <- [0.005*x | x <- [4..10]]
amt <- [1000*x | x <- [1..3]]
yrs <- [1..4]
return Loan {final = (2 `dp`) $ fromInteger amt*(1+ir)^yrs,
rate = ir,
loan = amt,
years = yrs}

这得益于更少的逗号,并且更容易更改 <- 的顺序行来更改答案的顺序。您可以将额外内容添加到您的 Loan与他们一起记录和计算。您会得到如下输出:

*Main> printloans loans'
Loan {final = 1020.0, rate = 2.0e-2, loan = 1000, years = 1}
Loan {final = 1040.4, rate = 2.0e-2, loan = 1000, years = 2}
Loan {final = 1061.21, rate = 2.0e-2, loan = 1000, years = 3}
Loan {final = 1082.43, rate = 2.0e-2, loan = 1000, years = 4}
Loan {final = 2040.0, rate = 2.0e-2, loan = 2000, years = 1}
Loan {final = 2080.8, rate = 2.0e-2, loan = 2000, years = 2}
...
...

编辑:

你在其他地方告诉我你想要类似 ir_5% yrs_3 amt_4000 tot_4360.5 的输出。它更丑陋,但这是一种做这种事情的方法:

loans'' = do
ir <- [0.005*x | x <- [4..10]]
amt <- [1000*x | x <- [1..3]]
yrs <- [1..4]
let final = (2 `dp`) $ fromInteger amt*(1+ir)^yrs
return $ "final_" ++ show final
++ ", ir_" ++ show ((2 `dp`) $ ir*100.0) -- rounded away a rounding error in 3.5%
++ "%, amt_" ++ show amt
++ ", yrs_" ++ show yrs

当你这样做时mapM_ putStrLn loans''你会得到像这样的输出

final_1020.0,  ir_2.0%,  amt_1000,  yrs_1
final_1040.4, ir_2.0%, amt_1000, yrs_2
final_1061.21, ir_2.0%, amt_1000, yrs_3
final_1082.43, ir_2.0%, amt_1000, yrs_4
final_2040.0, ir_2.0%, amt_2000, yrs_1
....

但我认为记录类型更好 - 它的输出更容易阅读,并且字符串的困惑更少。

关于haskell - 基于列表制作我自己的一元类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12122376/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com