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 Monad
instance 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 (>>=)
and return
in do-blocks, you can use a language extension with GHC:
{-# LANGUAGE NoImplicitPrelude #-}
module ListMon where
import Prelude hiding ((>>=), return)
(>>=) :: [a] -> (a -> [b]) -> [b]
xs >>= foo = case xs of
[] -> [undefined]
[x] -> foo x ++ foo x
ys -> take 10 $ concatMap foo $ take 5 ys
return :: a -> [a]
return x = [x,x,x]
someList :: [Int]
someList = do
k <- [1 .. 4]
h <- [2 .. 3]
return (k + 12*h)
resulting in
$ ghci ListMon
{- snip loading messages -}
[1 of 1] Compiling ListMon ( ListMon.hs, interpreted )
Ok, modules loaded:
*ListMon> someList
[25,25,25,37,37,37,26,26,26,38,38,38,27,27,27,39,39,39,28,28,28,40,40,40]
With NoImplicitPrelude
, desugaring of do-notation uses whatever (>>=)
and return
are in scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With