I’d like to supply my own instance for the list monad. Unfortunately, the following causes a duplicate instance declaration error when compiling.
myReturn :: a -> [a]
myBind :: [a] -> (a -> [b]) -> [b]
instance Monad [] where
return = myReturn
(>>=) = myBind
From the documentation, it seems like it’s not possible to hide instance declarations when importing, and since the list monad instance is already declared in the prelude, I guess I can’t get rid of the import itself either.
I figured that maybe I could at least rebind (>>=) and return so that I would be able to use do blocks using my own implementation since do blocks are supposedly just syntactic sugar for applications of (>>=) and (>>).
let
return = myReturn
(>>=) = myBind
in
do
item1 <- list1
item2 <- list2
return (item1, item2)
Unfortunately, it seems like do blocks get their (>>=) from somewhere else, because it’s still using the (>>=) of the default list monad instance.
Is there any way to make my implementations of (>>=) and return an instance of list monad, or at least a way to use them with do blocks?
You cannot define another
Monadinstance for lists, in some circumstances you can define a newtype to work around that, but you’d have to manually lift all list functions to the newtype to use them.To just use your own
(>>=)andreturnin do-blocks, you can use a language extension with GHC:resulting in
With
NoImplicitPrelude, desugaring of do-notation uses whatever(>>=)andreturnare in scope.