You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Functions that construct vectors with a known length should be able to produce the spine fully lazily. For example, I don't think there's a good reason why map (const 0) (undefined :: Vec 5 ()) should bottom out.
So I propose rewriting the vector functions a la the following examples:
map :: forall n a b. (KnownNat n) => (a -> b) -> Vec n a -> Vec n b
map f = go (toUNat SNat)
where
go :: forall n. UNat n -> Vec n a -> Vec n b
go UZero ~Nil = Nil
go (USucc n) ~(x :> xs) = f x :> go n xs
zipWith :: forall n a b c. (KnownNat n) => (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c
zipWith f = go (toUNat SNat)
where
go :: forall n. UNat n -> Vec n a -> Vec n b -> Vec n c
go UZero ~Nil ~Nil = Nil
go (USucc n) ~(x :> xs) ~(y :> ys) = f x y :> go n xs ys
(I'm including zipWith here to demonstrate how nicely unbiased it becomes with this technique).
The text was updated successfully, but these errors were encountered:
As @kleinreact can attest to, I have real-life code where, due to zipWith being unnecessarily lazy in its first argument's spine, f <$> x <*> y loops, whereas pure f <*> x <*> y works, which can be hella confusing unless one is aware of zipWith's details.
Functions that construct vectors with a known length should be able to produce the spine fully lazily. For example, I don't think there's a good reason why
map (const 0) (undefined :: Vec 5 ())
should bottom out.So I propose rewriting the vector functions a la the following examples:
(I'm including
zipWith
here to demonstrate how nicely unbiased it becomes with this technique).The text was updated successfully, but these errors were encountered: