In retrospect, was burning bridges a mistake?

newtype NonZero a = NonZero a

(/) :: Fractional a => a -> NonZero a -> a
(/) x y = ...

unitNonZero :: Num a => a -> NonZero a
unitNonZero x | x /= 0 = NonZero x

bindNonZero :: Num a => NonZero a -> (a -> NonZero b) -> NonZero b
bindNonZero (NonZero x) k = k x
divide :: Natural -> Natural -> Natural
divide x y | x < y = 0
           | otherwise = 1 + divide (x - y) y

divide x 0 = (\ y -> 1 + divide (x - y) y) 0  {- x >= y -}
           = 1 + divide (x - 0) 0)            {- application -}
           = 1 + divide x 0                   {- (-) identity -}
           = 1 + ⊥                            {- (divide x 0) regresses infinitely -}
           = ⊥                                {- (+) strict -}

…hence you either accept that division can fail:

(/) :: Fractional a => a -> a -> a

…or you make it annoyingly explicit that it doesn’t:

  • (/) :: Fractional a => a -> NonZero a -> a
    
  • (/) :: Fractional a => a -> a -> Maybe a
    

That would have been an interesting experience to rewrite everything in Haskell which relies on division to use the more explicit style for use in that course - the students must have been very impressed!


This is off topic though, so I’d recommend we don’t go on about it.

Agreed.