我有一個簡單的程序(這是CCC 2012第二個問題),它需要一個數字列表,並確定是否有任何嚴格的增加/減少/常量序列進行。例如:Haskell:懶惰影響解析方法
1 2 3 4 7 8 => Increasing
5 1 -2 -100 => Decreasing
9 9 9 9 9 9 => Constant
1 2 3 4 5 0 => Nothing
當我編碼時,我被哈斯克爾的智慧完全吹走了。出於某種原因,當我在交互式輸入數字時輸入stdin,在我甚至完成之前就已經給出了答案!我認爲這是一個錯誤,但後來我愚蠢地認識到,哈斯克爾的懶惰(我認爲?)自己決定,在我輸入1
,2
,3
,0
後,無論發生什麼後,結果都會是Nothing
,所以很高興輸出。
不幸的是,當我改變
let readings = map (read :: (Read a, Num a) => String -> a) $ lines input
到
let readings = parse $ lines input
與parse
被讀取數字輸入的更安全的方法,因爲
maybeRead :: (Read a) => String -> Maybe a
maybeRead = fmap fst . listToMaybe . filter (null . dropWhile isSpace . snd) . reads
parse :: (Read a) => [String] -> [a]
parse xs =
let entries = map maybeRead xs
in if all isJust entries
then map fromJust entries
else []
它不再執行此實現。
爲什麼?
編輯:更多的代碼
-- | Zip together adjacent list elements as pairs in a new list.
zipPairs :: [a] -> [(a, a)]
zipPairs xs = zip (init xs) (tail xs)
-- | Return True if all elements of a given list are equal.
constant :: (Eq a) => [a] -> Bool
constant xs = all (== head xs) (tail xs)
-- | Return the order that the elements of a list are sorted in, if they form
-- a strictly increasing (Just LT), decreasing (Just GT) or constant (Just EQ)
-- sequence. If there is no pattern, return Nothing.
order :: (Ord a) => [a] -> Maybe Ordering
order xs =
let orders = map (\(x, y) -> x `compare` y) (zipPairs xs)
in if constant orders then Just (head orders) else Nothing
,然後在main
我有
let readings = parse $ lines input
putStrLn $ if null readings
then "bad input"
else case order readings of
Just EQ -> "Constant"
Just LT -> "Diving"
Just GT -> "Rising"
Nothing -> "Nothing"
+1表示頓悟的啓示;)。 – gphilip 2012-03-04 08:23:33