ozh*_*ank 6 haskell integer-arithmetic
我写了以下内容来帮助大孩子们完成他们的家庭教育工作,并通过学习如何编程来保持思维工作(我认为haskell听起来很棒).
main :: IO ()
main = do
putStrLn "Please enter the dividend :"
inputx <- getLine
putStrLn "Please enter the divisor :"
inputy <- getLine
let x = (read inputx) :: Int
let y = (read inputy) :: Int
let z = x `div` y
let remain = x `mod` y
putStrLn ( "Result: " ++ show x ++ " / " ++ show y ++ " = " ++ show z ++ " remainder " ++ show remain )
putStrLn ( "Proof: (" ++ show y ++ " x " ++ show z ++ ") = " ++ show (y * z) ++ " + " ++ show remain ++ " = " ++ show ((y * z) + remain))
putStrLn ( "Is this what you had? ")
Run Code Online (Sandbox Code Playgroud)
他们这样做更整洁/更好/更好/更紧凑吗?
它将受益于一个关键原则:尽可能将您的纯代码与IO分开.这将使您的程序扩展并保持main简洁.很多let大main的不是一个非常实用的方法,并且随着代码的增长,往往会变得更加混乱.
使用类型签名,readLn这实际上fmap read getLine有助于减少一些残余.(如果你不熟悉fmap,请访问问题,如何使用funk在haskell中工作?.fmap确实是一个非常灵活的工具.)
getInts :: IO (Int, Int)
getInts = do
putStrLn "Please enter the dividend :"
x <- readLn
putStrLn " Please enter the divisor :"
y <- readLn
return (x,y)
Run Code Online (Sandbox Code Playgroud)
现在正在处理中.如果我对这种数据做了更多,或者更频繁,我会使用记录类型来存储红利,除数,商和余数,所以请记住未来,但这在这里是一种过度杀伤力.
我hackishly返回一个列表,而不是一个元组,这样我就可以使用map到show所有这些:
sums :: (Int, Int) -> [Int]
sums (x,y) = [x, y, q, r, y * q, y * q + r] where
q = x `div` y
r = x `mod` y
Run Code Online (Sandbox Code Playgroud)
拼图的最后一块是输出.我再次喜欢在IO之外生成这个,然后我可以mapM_ putStrLn稍后再打印每一行.我更喜欢这个采取记录类型,但我容忍一个字符串列表作为输入,因为我假设我已经shown.
explain :: [String] -> [String]
explain [x,y,q,r,yq,yq_r] =
[ concat ["Result: ", x, " / ", y, " = ", q, " remainder ", r]
, concat ["Proof: (", y, " x ", q, ") + ", r, " = ", yq, " + ", r, " = ", yq_r]
, "Is this what you had? "]
Run Code Online (Sandbox Code Playgroud)
现在,我们可以写main为
main = do (x,y) <- getInts
let ns = map show ( sums (x,y) )
es = explain ns
mapM_ putStrLn es
Run Code Online (Sandbox Code Playgroud)
或者更简洁,通过将函数组合在一起explain . map show . sums,并将其应用于getInts使用的输出fmap:
main :: IO ()
main = fmap (explain . map show . sums) getInts
>>= mapM_ putStrLn
Run Code Online (Sandbox Code Playgroud)
您可能会注意到我+r在证明中添加了一个=总是意味着=,这是正确的数学用法,而镜像的Haskell的含义为=.