[Haskell-cafe] Function hanging in infinite input
martin
martin.drautzburg at web.de
Sun Apr 26 13:20:29 UTC 2015
Hello all,
I was trying to implement >>= (tBind) on my "Temporal" data type and found that it hangs on an operation like
takeInitialPart $ infiniteTemporal >>= (\x -> finiteTemporal)
I am pretty sure the result is well defined and by no means infinite. Also the code works on finite Temporals. How does
one address such problems?
I attach the relevant pieces of code, in case someone would be so kind and inspect or run it. Feel free to point out any
flaws as I might be completely off-track.
If you call ex10 in GHCI, you get no result. The line marked with "< here" is executed over and over, but apparently
without contributing to the result. The debugger shows, that "hd" does have a correct, finite value each time and that
"tpr" is consumed as expected.
-- -- -- -- -- -- -- -- -- examples -- -- -- -- -- -- --
ex1 = Temporal [(DPast, 1), (T 3,3), (T 7, 7)] :: Temporal Int
ex10 = tUntil (T 5) $ outer `tBind` \_ -> ex1 :: Temporal Int
where
outer = Temporal $ (DPast,0):[(T (fromIntegral t), t)| t <- [5,10 ..]]
-- -- -- -- -- -- -- -- -- tBind -- -- -- -- -- -- -- --
-- Changed (Temporal a) to (Temporal Int) for debugging
tBind :: (Temporal Int) -> (Int -> Temporal Int) -> Temporal Int
tBind tpr f
-- tpr is infinite in this example, let's forget these cases
-- | tNull tpr = error "empty Temporal"
-- | tNull (tTail tpr) = laties
| otherwise = let hd = (tUntil (tTt tpr) laties)
in hd `tAppend` (tTail tpr `tBind` f) -- < here
where
laties = switchAt (tTh tpr) ( f (tVh tpr))
tTail (Temporal xs) = Temporal (tail xs)
tAppend (Temporal as) (Temporal bs) = Temporal (as ++ bs)
switchAt t tpx
| tNull (tTail tpx) = Temporal (tot tpx)
| between t (tTh tpx) (tTt tpx) = Temporal (tot tpx)
| otherwise = switchAt t (tTail tpx)
where
tot (Temporal ((ty,vy):xs)) = ((max t ty, vy):xs)
between t x y = t >= x && t < y
-- -- -- -- -- -- -- -- -- helpers -- -- -- -- -- -- -- --
data Time = DPast | T Integer deriving (Eq, Show) -- DPast is "distant past"
instance Ord Time
where
compare DPast DPast = EQ
compare DPast _ = LT
compare _ DPast = GT
compare (T t1) (T t2) = compare t1 t2
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
data Temporal a = Temporal [(Time, a)] deriving (Eq, Show)
tVh :: Temporal a -> a
tVh = snd . head . toList -- value head
tTt, tTh :: Temporal a -> Time
tTt = fst . head . tail . toList -- time tail
tTh = fst . head . toList -- time head
tNull = null . toList
tUntil :: Time -> Temporal a -> Temporal a
tUntil t (Temporal xs) = Temporal $ (takeWhile (\(tx, vx) -> tx > t)) xs
toList :: Temporal a -> [(Time, a)]
toList (Temporal xs) = xs
More information about the Haskell-Cafe
mailing list