我有一个简单的程序(这是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