I want to create a different classes of side-effecty functions, so I can mark some of the side-effects as safer than other ones.
I'd like to create a newtype over the Fay
side-effect monad and use it in the do notation, so I declare it like this:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE PackageImports #-}
import "base" Control.Monad
newtype ReadFay a = ReadFay { readFay :: Fay a } deriving Monad
A this point, the compiler cannot find the base
package. It is possible to do it in fay somehow?
I can still create my own versions of >>=
, return
, etc. for the ReadFay
, but being able to use it in do notation would be nice.
Or, is there a better way, how to create a different classes of side-effect than this my approach?
Looks like I need to enable
{-# LANGUAGE RebindableSyntax #-}
to override the functions, that the do notation is calling.
Then I need to implement the wrapping and unwrapping to/from the newtype in the functions that I plan to use in the do notation and shadow the Prelude
ones:
myFayReturn :: a -> ReadFay a
myFayReturn x = ReadFay $ return x
myFayBind :: ReadFay a -> (a -> ReadFay b) -> ReadFay b
myFayBind = \a b -> ReadFay $ runReadFay a >>= (runReadFay . b)
newtype ReadFay a = ReadFay { runReadFay :: Fay a }
doNotation :: ReadFay ()
doNotation = let
x >>= y = myFayBind x y
return = myFayReturn
in do
u <- ReadFay $ putStrLn "A"
return ()