I am trying to understand Monads and I did a practice question: For the problem I do two things take in a function and an Integer, than I process it in the following manner: I take the value the int supplied and than split the integer like so:
3 -> (2,1) (1,2)
4 -> (3,1) (2,2) (1,3)
so on.
Which works and is implemented as follows:
numberSplit :: Int -> [(Int,Int)]
numberSplit 0 = []
numberSplit 1 = []
numberSplit n = numberSplitHelper 1 (n - 1)
--Helper functions --
numberSplitHelper :: Int -> Int -> [(Int, Int)]
numberSplitHelper 0 0 = []
numberSplitHelper 0 1 = []
numberSplitHelper 1 0 = []
numberSplitHelper 1 1 = [(1, 1)]
numberSplitHelper n 1 = [(n, 1)]
numberSplitHelper n m = (n, m) : numberSplitHelper (n 1) (m - 1)
Afterwords I will apply the function recursively to every value in the list returned from the numberSplit function and I am trying to do it with monads as a practice for monads. So for example if I input in:
(sort
(andExpressionsAtSize
(\ i -> if i == 1 then
[EBase True,EBase False]
else if i == 2 then
[ENot (EBase True),ENot (EBase False)]
else [])
3))
My expected output is:
[EAnd (EBase False,EBase False)
,EAnd (EBase False,EBase True)
,EAnd (EBase True,EBase False)
,EAnd (EBase True, EBase True)]
I attempted to do the following:
andExpressionsAtSize :: (Int -> [Expression]) -> Int -> [Expression]
andExpressionsAtSize f 0 = []
andExpressionsAtSize f n = do
intList <- numberSplit n
intList >>= f
It gives me the following error:
Couldn't match type ‘(,) Int’ with ‘[]’
Expected: [Expression]
Actual: (Int, Expression)
Based on my understanding of the List Monad it does the following:
1. It takes in a list.
2. Applies the function on the left hand side to the list recursively.
So it would apply f to the head all the way to the tail. So based on that understanding
intList >>= f
Should return a type of [Expression] which it does not, this confuses me, can someone clarify what is happening?
Edit: Some people pointed out that I never used EAnd, I forgot to mention that in the output every element should be joined by an EAnd.
CodePudding user response:
intList
is not a list, as its name might suggest! In the snippet
do
{- ... -}
x <- y
{- here -}
if y
is a list, then x
will be one of the elements of the list in the continuation marked here
. You write:
do
intList <- numberSplit n
{- ... -}
Since numberSplit n
is a list, intList
will be a member of that list -- that is, a pair of type (Int, Int)
.
(I believe this is your core confusion, and once corrected you will have some ideas about things to try to fix the remainder of your code; but if this belief is incorrect say a bit about where I've gone wrong and I'll try to help further.)