@@ -4,6 +4,7 @@
44{-# LANGUAGE TemplateHaskell #-}
55{-# LANGUAGE ConstraintKinds #-}
66{-# LANGUAGE ScopedTypeVariables #-}
7+{-# LANGUAGE LambdaCase #-}
78module Main where
89
910import Control.Ether.Tags
@@ -13,6 +14,7 @@ import Control.Monad.Ether.Reader
1314import Control.Monad.Ether.State
1415import qualified Control.Monad.Ether.Implicit.Reader as I
1516import qualified Control.Monad.Ether.Implicit.State as I
17+import qualified Control.Monad.Ether.Implicit.Except as I
1618import qualified Control.Monad.Reader as T
1719import qualified Control.Monad.State as T
1820
@@ -140,3 +142,28 @@ factorial a = I.runState (I.runReaderT recurseCore a) (0 :: Int)
140142
141143factorial' :: Int -> (Int, Int)
142144factorial' a = factorial (a :: Int)
145+
146+data DivideByZero = DivideByZero
147+ deriving (Show)
148+data NegativeLog = NegativeLog
149+ deriving (Show)
150+
151+exceptCore
152+ :: ( Floating a, Ord a
153+ , I.MonadExcept DivideByZero m
154+ , I.MonadExcept NegativeLog m
155+ ) => a -> a -> m a
156+exceptCore a b = do
157+ if b == 0
158+ then I.throw DivideByZero
159+ else
160+ let d = a /b
161+ in if d < 0
162+ then I.throw NegativeLog
163+ else return $ log (a / b)
164+
165+exceptCore' :: Double -> Double -> String
166+exceptCore' a b
167+ = either (\NegativeLog -> "nl") id
168+ $ I.runExcept
169+ (either (\DivideByZero -> "dz") show <$> I.runExceptT (exceptCore a b))