Haskell error: could not combine type 'a' with 'b'

I am new to Haskell and have this piece of code:

import Control.Monad

data NestedList a = Elem a | List [NestedList a] deriving (Show)

instance Monad NestedList where
    return a = List [Elem a]
    (List (Elem a: xs)) >>= f = let a' = f a in a' `joinLists` xs

func :: a -> NestedList a
func a = List ([Elem a] ++ [Elem a])

joinLists :: NestedList a -> [NestedList a] -> NestedList a
joinLists (List a) b = List (a ++ b)

main = do let a = List [Elem 1, Elem 2] >>= func
          print a

What I'm trying to do is take a list with elements, copy the first element of the list and add a tail to this list. So, List [Elem 1, Elem 2] will be equal to List [Elem 1, Elem 1, Elem 2]. I know this is not a good example of using Monads, but this is for the sake of learning.

I get an error message:

Couldn't match type 'a' with 'b'
   'a' is a rigid type variable bound by
       the type signature for
          '>>= :: NestedList a -> (a -> NestedList b) -> NestedList b
   'b' is a rigid type variable bound by
       the type signature for
          '>>= :: NestedList a -> (a -> NestedList b) -> NestedList b
   Expected type: [NestedList b]
   Actual type: [NestedList a]
   In the second argument of 'joinLists', namely 'xs'

I understand that the error is that it expects another variable of type NestedList. What is the problem?

+4
source share
2 answers

For reference, here is an example of a working monad NestedList. It is easy to verify that this instance satisfies the laws of the monad.

import Control.Monad

data NestedList a = Elem a | List [NestedList a] deriving (Show)

instance Monad NestedList where
    return x = Elem x
    (Elem x)  >>= f = f x
    (List xs) >>= f = List $ map step xs
        where step (Elem a) = f a
              step lst = lst >>= f

Here is the test program:

import Control.Monad

data NestedList a = Elem a | List [NestedList a] deriving (Show)

instance Monad NestedList where
    return x = Elem x
    (Elem x)  >>= f = f x
    (List xs) >>= f = List $ map step xs
        where step (Elem a) = f a
              step lst = lst >>= f


double :: a -> NestedList a
double a = List ([Elem a] ++ [Elem a])


add :: (Num a) => a -> a -> NestedList a
add a e = Elem $ a + e


main = do let a = Elem 1 >>= double
          let b = List [Elem 1, Elem 2] >>= double
          let c = List [Elem 2,List [Elem 3,Elem 4],Elem 5] >>= add 1
          print a
          print b
          print c

And his conclusion:

$ runhaskell t.hs 
List [Elem 1,Elem 1]
List [List [Elem 1,Elem 1],List [Elem 2,Elem 2]]
List [Elem 3,List [Elem 4,Elem 5],Elem 6]
+2

, Monads, .

, >>= . , , :

a → (a → a) → a

Haskell

a → (a → b) → b

, , .

, "", - "" .

+7

Source: https://habr.com/ru/post/1538979/


All Articles