0

I'm trying to chain together functions via the applicative functor pattern, but I'm having a problem compiling my code:

import Control.Applicative

buildMyList :: Float -> Float -> [Float]
buildMyList ul tick = [p | p <- [0,tick..ul]]

myFunctionChain :: [Float]
myFunctionChain = reverse <$> buildMyList 100 1

When I attempt to compile this I get the following compilation error:

Couldn't match type 'Float' with '[a0]'
Expected type: [[a0]]
  Actual type: [Float]
In the return type of call of 'buildMyList'

It seems to me that I haven't managed to match the expected return context with the actual context. Not having enough experience in this area, I cant get any further!

MasterMastic
  • 20,711
  • 12
  • 68
  • 90
Anthony W
  • 1,289
  • 2
  • 15
  • 28
  • 2
    You don't need `Applicative` here. Ordinary function application will do: `reverse (buildMyList 100 1)` or `reverse $ buildMyList 100 1`. – phadej Jan 26 '15 at 12:51
  • yes, I agree with you. It's meant to be a toy example, as I'm trying to understand why it doesn't work, so that I can build out my knowledge – Anthony W Jan 26 '15 at 12:55

1 Answers1

1

The Applicative could be better explained using bulldMyList. Assume you want to build an array of square matrix: [(0,0), (0,1), (0,2), (1, 0) ...]. Using list comprehensions:

buildMyMatrix :: Int -> Int -> [(Int, Int)]
buildMyMatrix maxX maxY = [(x, y) | x <- [0..maxX], y <- [0..maxY]]

Using applicative combinators it can be rewritten as:

buildMyMatrix maxX maxY = pure (\x y -> (x, y)) <*> [0..maxX] <*> [0..maxY]

And according to applicative laws we can rewrite pure f <*> x = f <$> x, for all f and x:

buildMyMatrix maxX maxY = (\x y -> (x, y)) <$> [0..maxX] <*> [0..maxY]

I had to use slightly more complicated buildMyMatrix, as your buildMyList is too trivial to benefit from Applicative:

buildMyList :: Float -> Float -> [Float]
buildMyList ul tick = [p | p <- [0,tick..ul]]
buildMyList ul tick = id <$> [0,tick..ul] -- [by functor identity law]:
buildMyList ul tick = [0,tick..ul]
phadej
  • 11,947
  • 41
  • 78
  • thanks for this. I guess I was just trying to understand how I can chain together functions that are functors, in an elegant way. I suppose I could use do notation – Anthony W Jan 26 '15 at 13:28
  • If you want to chain functions of the form `Applicative f => a -> f b` or `Monad m => a -> m b`, there are many different ways, depending how you'd like to chain them. [Recent question](http://stackoverflow.com/questions/28150825/how-can-i-use-with-a-maybe-a) has already two answers, which are probably interesting to work thru (e.g. which instances apply). I find both obscure, but they show the power of the abstraction. – phadej Jan 26 '15 at 13:40