Repository navigation
Conversation
| r@(e :*: x') -> if e then runEqM g x' else r | ||
| instance (Eq m, Monoid m) => Semigroup (ShortCircuit m a) where | ||
| f <> g = ShortCircuit $ \x -> case runShortCircuit f x of | ||
| r@(e :*: x') -> if e == mempty then runShortCircuit g x' else r |
There was a problem hiding this comment.
I assume e == All True will always optimize to if e
|
I'm not sure about this. If I think of generalizing this, I would proceed a bit differently. First, we need the property that data Which = L | R
instance Semigroup a => ChoosesOne a where
-- Law: (x <> y) == case sappendWhich x y of { L -> x; R -> y }
sappendWhich :: a -> a -> WhichThen we can have choosePair :: ChoosesOne a => StrictPair s a -> StrictPair s a -> StrictPair s a
choosePair p1@(_ :*: x1) p2(_ :*: x2) = case sappendWhich x1 x2 of { L -> p1; R -> p2 }
newtype ChooseWithState s a = CWS (s -> StrictPair s a)
instance ChoosesOne a => Semigroup (ChooseWithState s a) where
CWS f1 <> CWS f2 = CWS $ \s0 ->
let p1@(_ :*: s1) = f1 s0
in choosePair p1 (f2 s1)With another property that the semigroup has left-zeros, we can optimize it to the current implementation. instance Semigroup a => HasLeftZeros a where
-- Law: isLeftZero x <=> x <> y == x
isLeftZero :: a -> Bool
newtype ShortCircuitChooseWithState s a = SCCWS (s -> StrictPair s a)
instance (ChoosesOne a, HasLeftZeros a) => Semigroup (ShortCircuitChooseWithState s a) where
SCCWS f1 <> SCCWS f2 = SCCWS $ \s0 ->
let p1@(x1 :*: s1) = f1 s0
in if isLeftZero x1
then p1
else f2 s1All this is to say that I find it convoluted and don't see the benefit in trying to generalize it. |
All good points, this was half-baked since I mostly mechanically de-duplicated. Let me try to make this more precise. The whole point is to be able to do short-circuit, which means we can't always apply That is, for first f (a :*: b) = f a :*: b
instance HasLeftZeros a => Monoid (ShortCircuit k v) where
ShortCircuit f <> ShortCircuit g = ShortCircuit $ \x -> case f x of
r@(m :*: x') -> if isLeftZero m then r else first (m <>) (g x')
I wouldn't say convoluted, but agree with not trying to generalize at this point since we have no instances of partial shortcircuit that actually uses
I don't think it's what we want here after all, but FWIW there's https://hackage.haskell.org/package/patch-0.0.8.4/docs/Data-Monoid-DecidablyEmpty.html |
Name is tentative