とにかく、楽しく過ごしましょう。
loop = do
let maxi = 0
let maxIdx = 0
let idx = 0
let idxN = 0
replicateM 5 $ do
input_line <- getLine
let element = read input_line :: Int
if maxi < element
then do
let maxi = element
let maxIdx = idx
hPutStrLn stderr "INNER CHECK"
else
hPutStrLn stderr "OUTER CHECK"
let idx = idxN + 1
let idxN = idx
print maxIdx
loop
は、特にハスケルコードではありません(特に正しくはありません)。
ハスケリエならば作ろう。
ここでは何をしますか?私たちは無限のループを持っています。無限ループは、5行目を読んでいて、それに何かをしてから、特別な理由なしに再び呼びます。
のは、それを分割してみましょう:
import Control.Monad
readFiveLines :: IO [Int]
readFiveLines = replicateM 5 readLn
addIndex :: [Int] -> [(Int, Int)]
addIndex xs = zip xs [0..]
findMaxIndex :: [Int] -> Int
findMaxIndex xs = snd (maximum (addIndex xs))
loop ::()
loop = loop
main :: IO()
main = do xs <- readFiveLines
putStrLn (show (findMaxIndex xs))
snd
はタプルから2番目の要素を返します。 readLn
は本質的にread . getLine
です。 zip
は2つのリストを取り、ペアのリストを返します。 maximum
が最大値を見つけます。
私はloop
を元の美しさにそのまま残しました。
あなたはsomething (huge expression)
が(単にその右オペランドにその左オペランドを適用$
)something $ huge expression
と交換することができることを覚えていればあなたもHaskellierすることができ、かつ機能が.
と組み合わせることができます:f (g x)
は(f . g) x
、またはf . g $ x
と同じです(参照してください?それはまた、左側のために働いている!)。また、zip x y
デバッグプリントとしてx `zip` y
import Control.Monad
readFiveLines :: IO [Int]
readFiveLines = replicateM 5 readLn
addIndex :: [Int] -> [(Int, Int)]
addIndex = (`zip` [0..])
findMaxIndex :: [Int] -> Int
findMaxIndex = snd . maximum . addIndex
main :: IO()
main = do xs <- readFiveLines
putStrLn . show . findMaxIndex $ xs
ように書き換えることができ、パッケージはありstderr
にDebug.Trace
と(したがって、その名前show
でフォーマットされた)最初の引数を印刷する機能traceShow
と呼ばれ、その第二のを返します引数:
findMaxIndex :: [Int] -> Int
findMaxIndex = snd . (\xs -> traceShow xs (maximum xs)) . addIndex
あなたはどんな式にタップして、に来るのかを確認することができます(と値は約何 - することができますshow
タプル、リストなど)
出典
2016-06-01 19:54:26
alf
各繰り返しで 'maxi'を印刷してみてください。それはあなたにヒントを与えるはずです。それに、あなたがハスケルを使っているとは思わない。 – alf
** hPutStrLn stderrのint値をどのようにpringできますか?**?はい、私はそれを最善の方法でusuingしていないことを知っています、私はそれを試しています:)。 – SoldierKB
ポイントは、それらは_vary._ではないという点で "変数"ではありません。これらは値であり、スコープはあなたが現在行っている 'do'演算子に限定されています。 – alf