Home > Blockchain >  Strange behavior from monad in Haskell
Strange behavior from monad in Haskell

Time:10-19

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.)

  • Related