haskellmonadsderivingderivingvia# defining new monad instance

A few days ago I was trying to prove monad laws by creating a new monad instance but I found myself stuck at defining the new monad instance.

```
{-# LANGUAGE DeriveFunctor, InstanceSigs #-}
import Control.Monad
newtype Test a = Test { getTest :: [Maybe a] }
deriving Functor
instance Applicative Test where
pure = return
(<*>) = liftM2 ($)
instance Monad Test where
return :: a -> Test a
return a = Test $ [Just a]
(>>=) :: Test a -> (a -> Test b) -> Test b
g >>= f = concat (map f g) --Tried to do something like this
```

I tried something following the list monad definition, but is stuck because concat expects [[a]] but here it gets [Test b], so maybe there are other functions available or is there a way to make concat work on the newType? Any suggestions are appreciated. Thanks.

Solution

Unlike `type`

aliases, `newtype`

wrappers need to be manually applied and removed. Replace `g >>= f = concat (map f g)`

with `Test g >>= f = Test $ concat (map (getTest . f) g)`

.

This will leave you with only one more type error: `g`

has type `[Maybe a]`

instead of the needed `[a]`

. We can tack on a `catMaybes`

(needs `import Data.Maybe`

) to take care of that: `Test g >>= f = Test $ concat (map (getTest . f) $ catMaybes g)`

. Now it compiles.

Unfortunately, this instance isn't lawful. I'll leave it as an exercise for the reader to establish why not, and whether it can be easily fixed.

- Comparing lists in Haskell
- Is there a non-identity monad morphism M ~> M that is monadically natural in M?
- Problem with loading module ‘Distribution.Simple’
- Improving efficiency in Stirling numbers calculation
- Does sequencing an infinite list of IO actions by definition result in a never-ending action? Or is there a way to bail out?
- How to call pgQuery from postgresql-query?
- How to avoid whitespace after a tag (link) in Hamlet templates?
- Understanding type-directed resolution in Haskell with existential types
- Why is seq bad?
- Understanding bind function in Haskell
- How to create route that will trigger on any path in Servant?
- How do I use a global state in WAI middleware?
- nixos 23.11 cabal install mysql-simple problem - "Missing (or bad) C libraries"
- Is there a way to kill all forked threads in a GHCi session without restarting it?
- Why can an invalid list expression such as 2:1 be assigned to a variable, but not printed?
- Iterate over a type level list and call a function based on each type in the list
- How does this solution of Project Euler Problem 27 in the Haskell Wiki work?
- Why `Monad` is required to use `pure`?
- Can't do partial function definitions in GHCi
- recommended way to convert Double -> Float in Haskell
- Haskell profiling understanding cost centre summary for anonymous lambda
- Why is Haskell fully declarative?
- GHC Generating Redundant Core Operations
- Question about Event firing in reflex-frp
- Using Haskell's "Maybe", type declarations
- How can I elegantly invert a Map's keys and values?
- Why there is no output for wrapped IO in Haskell?
- What are the definitions of Weather and Memory in xmobar repo?
- Serializing a Data.Text value to a ByteString without unnecessary \NUL bytes
- Using Haskell with VS Code